revert(format): Revert "chore(format): update to latest formatter"

This reverts commit 03627aa84d.
This commit is contained in:
Alex Rickabaugh
2016-04-12 09:40:37 -07:00
parent 03627aa84d
commit 60727c4d2b
527 changed files with 19247 additions and 13970 deletions
@@ -1,28 +1,43 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, el, AsyncTestCompleter, fakeAsync, tick, inject, SpyObject} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
el,
AsyncTestCompleter,
fakeAsync,
tick,
inject,
SpyObject
} from 'angular2/testing_internal';
import {SpyChangeDetector} from './spies';
import {ApplicationRef_, ApplicationRef, PlatformRef_} from 'angular2/src/core/application_ref';
import {Injector, Provider, APP_INITIALIZER} from 'angular2/core';
import {ChangeDetectorRef_} from 'angular2/src/core/change_detection/change_detector_ref';
import {PromiseWrapper, PromiseCompleter, TimerWrapper} from 'angular2/src/facade/async';
import {ListWrapper} from 'angular2/src/facade/collection';
import {ApplicationRef_, ApplicationRef, PlatformRef_} from "angular2/src/core/application_ref";
import {Injector, Provider, APP_INITIALIZER} from "angular2/core";
import {ChangeDetectorRef_} from "angular2/src/core/change_detection/change_detector_ref";
import {PromiseWrapper, PromiseCompleter, TimerWrapper} from "angular2/src/facade/async";
import {ListWrapper} from "angular2/src/facade/collection";
import {ExceptionHandler} from 'angular2/src/facade/exception_handler';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
export function main() {
describe('ApplicationRef', () => {
it('should throw when reentering tick', () => {
describe("ApplicationRef", () => {
it("should throw when reentering tick", () => {
var cd = <any>new SpyChangeDetector();
var ref = new ApplicationRef_(null, null, null);
ref.registerChangeDetector(new ChangeDetectorRef_(cd));
cd.spy('detectChanges').andCallFake(() => ref.tick());
expect(() => ref.tick()).toThrowError('ApplicationRef.tick is called recursively');
cd.spy("detectChanges").andCallFake(() => ref.tick());
expect(() => ref.tick()).toThrowError("ApplicationRef.tick is called recursively");
});
});
describe('PlatformRef', () => {
describe("PlatformRef", () => {
var exceptionHandler =
new Provider(ExceptionHandler, {useValue: new ExceptionHandler(DOM, true)});
describe('asyncApplication', () => {
describe("asyncApplication", () => {
function expectProviders(injector: Injector, providers: Array<any>): void {
for (let i = 0; i < providers.length; i++) {
let provider = providers[i];
@@ -30,7 +45,7 @@ export function main() {
}
}
it('should merge syncronous and asyncronous providers',
it("should merge syncronous and asyncronous providers",
inject([AsyncTestCompleter, Injector], (async, injector) => {
let ref = new PlatformRef_(injector, null);
let ASYNC_PROVIDERS = [new Provider(Foo, {useValue: new Foo()}), exceptionHandler];
@@ -43,18 +58,19 @@ export function main() {
});
}));
it('should allow function to be null',
it("should allow function to be null",
inject([AsyncTestCompleter, Injector], (async, injector) => {
let ref = new PlatformRef_(injector, null);
let SYNC_PROVIDERS = [new Provider(Bar, {useValue: new Bar()}), exceptionHandler];
ref.asyncApplication(null, SYNC_PROVIDERS).then((appRef) => {
expectProviders(appRef.injector, SYNC_PROVIDERS);
async.done();
});
ref.asyncApplication(null, SYNC_PROVIDERS)
.then((appRef) => {
expectProviders(appRef.injector, SYNC_PROVIDERS);
async.done();
});
}));
function mockAsyncAppInitializer(
completer: PromiseCompleter<any>, providers: Array<any> = null, injector?: Injector) {
function mockAsyncAppInitializer(completer: PromiseCompleter<any>,
providers: Array<any> = null, injector?: Injector) {
return () => {
if (providers != null) {
expectProviders(injector, providers);
@@ -64,54 +80,57 @@ export function main() {
};
}
it('should wait for asyncronous app initializers',
it("should wait for asyncronous app initializers",
inject([AsyncTestCompleter, Injector], (async, injector) => {
let ref = new PlatformRef_(injector, null);
let completer: PromiseCompleter<any> = PromiseWrapper.completer();
let SYNC_PROVIDERS = [
new Provider(Bar, {useValue: new Bar()}),
new Provider(
APP_INITIALIZER, {useValue: mockAsyncAppInitializer(completer), multi: true})
new Provider(APP_INITIALIZER,
{useValue: mockAsyncAppInitializer(completer), multi: true})
];
ref.asyncApplication(null, [SYNC_PROVIDERS, exceptionHandler]).then((appRef) => {
expectProviders(appRef.injector, SYNC_PROVIDERS.slice(0, SYNC_PROVIDERS.length - 1));
completer.promise.then((_) => async.done());
});
ref.asyncApplication(null, [SYNC_PROVIDERS, exceptionHandler])
.then((appRef) => {
expectProviders(appRef.injector,
SYNC_PROVIDERS.slice(0, SYNC_PROVIDERS.length - 1));
completer.promise.then((_) => async.done());
});
}));
it('should wait for async providers and then async app initializers',
it("should wait for async providers and then async app initializers",
inject([AsyncTestCompleter, Injector], (async, injector) => {
let ref = new PlatformRef_(injector, null);
let ASYNC_PROVIDERS = [new Provider(Foo, {useValue: new Foo()})];
let completer: PromiseCompleter<any> = PromiseWrapper.completer();
let SYNC_PROVIDERS = [
new Provider(Bar, {useValue: new Bar()}), new Provider(APP_INITIALIZER, {
useFactory: (injector) =>
mockAsyncAppInitializer(<any>completer, ASYNC_PROVIDERS, injector),
multi: true,
deps: [Injector]
})
new Provider(Bar, {useValue: new Bar()}),
new Provider(APP_INITIALIZER,
{
useFactory: (injector) => mockAsyncAppInitializer(
<any>completer, ASYNC_PROVIDERS, injector),
multi: true,
deps: [Injector]
})
];
ref.asyncApplication(
(zone) => PromiseWrapper.resolve(ASYNC_PROVIDERS),
[SYNC_PROVIDERS, exceptionHandler])
ref.asyncApplication((zone) => PromiseWrapper.resolve(ASYNC_PROVIDERS),
[SYNC_PROVIDERS, exceptionHandler])
.then((appRef) => {
expectProviders(
appRef.injector, SYNC_PROVIDERS.slice(0, SYNC_PROVIDERS.length - 1));
expectProviders(appRef.injector,
SYNC_PROVIDERS.slice(0, SYNC_PROVIDERS.length - 1));
completer.promise.then((_) => async.done());
});
}));
});
describe('application', () => {
it('should throw if an APP_INITIIALIZER returns a promise', inject([Injector], (injector) => {
describe("application", () => {
it("should throw if an APP_INITIIALIZER returns a promise", inject([Injector], (injector) => {
let ref = new PlatformRef_(injector, null);
let appInitializer = new Provider(
APP_INITIALIZER, {useValue: () => PromiseWrapper.resolve([]), multi: true});
expect(() => ref.application([appInitializer, exceptionHandler]))
.toThrowError(
'Cannot use asyncronous app initializers with application. Use asyncApplication instead.');
"Cannot use asyncronous app initializers with application. Use asyncApplication instead.");
}));
});
});
@@ -1,6 +1,16 @@
import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {isBlank, isPresent} from 'angular2/src/facade/lang';
import {ChangeDetectionStrategy, BindingRecord, ChangeDetectorDefinition, DirectiveIndex, DirectiveRecord, Lexer, Locals, Parser, ChangeDetectorGenConfig} from 'angular2/src/core/change_detection/change_detection';
import {
ChangeDetectionStrategy,
BindingRecord,
ChangeDetectorDefinition,
DirectiveIndex,
DirectiveRecord,
Lexer,
Locals,
Parser,
ChangeDetectorGenConfig
} from 'angular2/src/core/change_detection/change_detection';
import {reflector} from 'angular2/src/core/reflection/reflection';
import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities';
@@ -22,16 +32,16 @@ function _createBindingRecords(expression: string): BindingRecord[] {
}
function _createEventRecords(expression: string): BindingRecord[] {
var eq = expression.indexOf('=');
var eq = expression.indexOf("=");
var eventName = expression.substring(1, eq - 1);
var exp = expression.substring(eq + 2, expression.length - 1);
var ast = _getParser().parseAction(exp, 'location');
return [BindingRecord.createForEvent(ast, eventName, 0)];
}
function _createHostEventRecords(
expression: string, directiveRecord: DirectiveRecord): BindingRecord[] {
var parts = expression.split('=');
function _createHostEventRecords(expression: string,
directiveRecord: DirectiveRecord): BindingRecord[] {
var parts = expression.split("=");
var eventName = parts[0].substring(1, parts[0].length - 1);
var exp = parts[1].substring(1, parts[1].length - 1);
@@ -80,8 +90,8 @@ export function getDefinition(id: string): TestDefinition {
var variableBindings = [];
var eventRecords = _createBindingRecords(id);
var directiveRecords = [];
let cdDef = new ChangeDetectorDefinition(
id, strategy, variableBindings, eventRecords, [], directiveRecords, genConfig);
let cdDef = new ChangeDetectorDefinition(id, strategy, variableBindings, eventRecords, [],
directiveRecords, genConfig);
testDef = new TestDefinition(id, cdDef, null);
} else if (ListWrapper.indexOf(_availableEventDefinitions, id) >= 0) {
@@ -96,9 +106,9 @@ export function getDefinition(id: string): TestDefinition {
[_DirectiveUpdating.basicRecords[0], _DirectiveUpdating.basicRecords[1]], genConfig);
testDef = new TestDefinition(id, cdDef, null);
} else if (id == 'updateElementProduction') {
} else if (id == "updateElementProduction") {
var genConfig = new ChangeDetectorGenConfig(false, false, true);
var records = _createBindingRecords('name');
var records = _createBindingRecords("name");
let cdDef = new ChangeDetectorDefinition(id, null, [], records, [], [], genConfig);
testDef = new TestDefinition(id, cdDef, null);
}
@@ -120,13 +130,13 @@ export class TestDefinition {
*/
export function getAllDefinitions(): TestDefinition[] {
var allDefs = _availableDefinitions;
allDefs = ListWrapper.concat(
allDefs, StringMapWrapper.keys(_ExpressionWithLocals.availableDefinitions));
allDefs = ListWrapper.concat(allDefs,
StringMapWrapper.keys(_ExpressionWithLocals.availableDefinitions));
allDefs = allDefs.concat(StringMapWrapper.keys(_ExpressionWithMode.availableDefinitions));
allDefs = allDefs.concat(StringMapWrapper.keys(_DirectiveUpdating.availableDefinitions));
allDefs = allDefs.concat(_availableEventDefinitions);
allDefs = allDefs.concat(_availableHostEventDefinitions);
allDefs = allDefs.concat(['updateElementProduction']);
allDefs = allDefs.concat(["updateElementProduction"]);
return allDefs.map(getDefinition);
}
@@ -139,8 +149,8 @@ class _ExpressionWithLocals {
var bindingRecords = _createBindingRecords(this._expression);
var directiveRecords = [];
var genConfig = new ChangeDetectorGenConfig(true, true, true);
return new ChangeDetectorDefinition(
'(empty id)', strategy, variableBindings, bindingRecords, [], directiveRecords, genConfig);
return new ChangeDetectorDefinition('(empty id)', strategy, variableBindings, bindingRecords,
[], directiveRecords, genConfig);
}
/**
@@ -165,9 +175,8 @@ class _ExpressionWithLocals {
}
class _ExpressionWithMode {
constructor(
private _strategy: ChangeDetectionStrategy, private _withRecords: boolean,
private _withEvents: boolean) {}
constructor(private _strategy: ChangeDetectionStrategy, private _withRecords: boolean,
private _withEvents: boolean) {}
createChangeDetectorDefinition(): ChangeDetectorDefinition {
var variableBindings = [];
@@ -185,12 +194,12 @@ class _ExpressionWithMode {
});
if (this._withRecords) {
var updateDirWithOnDefaultRecord = BindingRecord.createForDirective(
_getParser().parseBinding('42', 'location'), 'a', (o, v) => (<any>o).a = v,
dirRecordWithDefault);
var updateDirWithOnPushRecord = BindingRecord.createForDirective(
_getParser().parseBinding('42', 'location'), 'a', (o, v) => (<any>o).a = v,
dirRecordWithOnPush);
var updateDirWithOnDefaultRecord =
BindingRecord.createForDirective(_getParser().parseBinding('42', 'location'), 'a',
(o, v) => (<any>o).a = v, dirRecordWithDefault);
var updateDirWithOnPushRecord =
BindingRecord.createForDirective(_getParser().parseBinding('42', 'location'), 'a',
(o, v) => (<any>o).a = v, dirRecordWithOnPush);
directiveRecords = [dirRecordWithDefault, dirRecordWithOnPush];
bindingRecords = [updateDirWithOnDefaultRecord, updateDirWithOnPushRecord];
@@ -198,16 +207,15 @@ class _ExpressionWithMode {
if (this._withEvents) {
directiveRecords = [dirRecordWithDefault, dirRecordWithOnPush];
eventRecords = ListWrapper.concat(
_createEventRecords('(event)=\'false\''),
_createHostEventRecords('(host-event)=\'false\'', dirRecordWithOnPush))
eventRecords =
ListWrapper.concat(_createEventRecords("(event)='false'"),
_createHostEventRecords("(host-event)='false'", dirRecordWithOnPush))
}
var genConfig = new ChangeDetectorGenConfig(true, true, true);
return new ChangeDetectorDefinition(
'(empty id)', this._strategy, variableBindings, bindingRecords, eventRecords,
directiveRecords, genConfig);
return new ChangeDetectorDefinition('(empty id)', this._strategy, variableBindings,
bindingRecords, eventRecords, directiveRecords, genConfig);
}
/**
@@ -227,29 +235,27 @@ class _ExpressionWithMode {
}
class _DirectiveUpdating {
constructor(
private _bindingRecords: BindingRecord[], private _directiveRecords: DirectiveRecord[]) {}
constructor(private _bindingRecords: BindingRecord[],
private _directiveRecords: DirectiveRecord[]) {}
createChangeDetectorDefinition(): ChangeDetectorDefinition {
var strategy = null;
var variableBindings = [];
var genConfig = new ChangeDetectorGenConfig(true, true, true);
return new ChangeDetectorDefinition(
'(empty id)', strategy, variableBindings, this._bindingRecords, [], this._directiveRecords,
genConfig);
return new ChangeDetectorDefinition('(empty id)', strategy, variableBindings,
this._bindingRecords, [], this._directiveRecords,
genConfig);
}
static updateA(expression: string, dirRecord): BindingRecord {
return BindingRecord.createForDirective(
_getParser().parseBinding(expression, 'location'), 'a', (o, v) => (<any>o).a = v,
dirRecord);
return BindingRecord.createForDirective(_getParser().parseBinding(expression, 'location'), 'a',
(o, v) => (<any>o).a = v, dirRecord);
}
static updateB(expression: string, dirRecord): BindingRecord {
return BindingRecord.createForDirective(
_getParser().parseBinding(expression, 'location'), 'b', (o, v) => (<any>o).b = v,
dirRecord);
return BindingRecord.createForDirective(_getParser().parseBinding(expression, 'location'), 'b',
(o, v) => (<any>o).b = v, dirRecord);
}
static basicRecords: DirectiveRecord[] = [
@@ -298,15 +304,16 @@ class _DirectiveUpdating {
'directNoDispatcher': new _DirectiveUpdating(
[_DirectiveUpdating.updateA('42', _DirectiveUpdating.basicRecords[0])],
[_DirectiveUpdating.basicRecords[0]]),
'groupChanges': new _DirectiveUpdating(
[
_DirectiveUpdating.updateA('1', _DirectiveUpdating.basicRecords[0]),
_DirectiveUpdating.updateB('2', _DirectiveUpdating.basicRecords[0]),
BindingRecord.createDirectiveOnChanges(_DirectiveUpdating.basicRecords[0]),
_DirectiveUpdating.updateA('3', _DirectiveUpdating.basicRecords[1]),
BindingRecord.createDirectiveOnChanges(_DirectiveUpdating.basicRecords[1])
],
[_DirectiveUpdating.basicRecords[0], _DirectiveUpdating.basicRecords[1]]),
'groupChanges':
new _DirectiveUpdating(
[
_DirectiveUpdating.updateA('1', _DirectiveUpdating.basicRecords[0]),
_DirectiveUpdating.updateB('2', _DirectiveUpdating.basicRecords[0]),
BindingRecord.createDirectiveOnChanges(_DirectiveUpdating.basicRecords[0]),
_DirectiveUpdating.updateA('3', _DirectiveUpdating.basicRecords[1]),
BindingRecord.createDirectiveOnChanges(_DirectiveUpdating.basicRecords[1])
],
[_DirectiveUpdating.basicRecords[0], _DirectiveUpdating.basicRecords[1]]),
'directiveDoCheck': new _DirectiveUpdating(
[BindingRecord.createDirectiveDoCheck(_DirectiveUpdating.basicRecords[0])],
[_DirectiveUpdating.basicRecords[0]]),
@@ -318,14 +325,20 @@ class _DirectiveUpdating {
'noCallbacks': new _DirectiveUpdating(
[_DirectiveUpdating.updateA('1', _DirectiveUpdating.recordNoCallbacks)],
[_DirectiveUpdating.recordNoCallbacks]),
'readingDirectives': new _DirectiveUpdating(
[BindingRecord.createForHostProperty(
new DirectiveIndex(0, 0), _getParser().parseBinding('a', 'location'), PROP_NAME)],
[_DirectiveUpdating.basicRecords[0]]),
'interpolation': new _DirectiveUpdating(
[BindingRecord.createForElementProperty(
_getParser().parseInterpolation('B{{a}}A', 'location'), 0, PROP_NAME)],
[])
'readingDirectives':
new _DirectiveUpdating(
[
BindingRecord.createForHostProperty(
new DirectiveIndex(0, 0), _getParser().parseBinding('a', 'location'), PROP_NAME)
],
[_DirectiveUpdating.basicRecords[0]]),
'interpolation':
new _DirectiveUpdating(
[
BindingRecord.createForElementProperty(
_getParser().parseInterpolation('B{{a}}A', 'location'), 0, PROP_NAME)
],
[])
};
}
@@ -377,8 +390,8 @@ var _availableDefinitions = [
'{z: a}',
'name | pipe',
'(name | pipe).length',
'name | pipe:\'one\':address.city',
'name | pipe:\'a\':\'b\' | pipe:0:1:2',
"name | pipe:'one':address.city",
"name | pipe:'a':'b' | pipe:0:1:2",
'value',
'a',
'address.city',
@@ -1,6 +1,20 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, tick, fakeAsync} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
tick,
fakeAsync
} from 'angular2/testing_internal';
import {ChangeDetectorRef, ChangeDetectorRef_} from 'angular2/src/core/change_detection/change_detector_ref';
import {
ChangeDetectorRef,
ChangeDetectorRef_
} from 'angular2/src/core/change_detection/change_detector_ref';
import {SpyChangeDetector} from '../spies';
@@ -1,13 +1,50 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, tick, fakeAsync} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
tick,
fakeAsync
} from 'angular2/testing_internal';
import {SpyChangeDispatcher} from '../spies';
import {CONST_EXPR, isPresent, isBlank, isNumber, isJsObject, FunctionWrapper, NumberWrapper, normalizeBool} from 'angular2/src/facade/lang';
import {
CONST_EXPR,
isPresent,
isBlank,
isNumber,
isJsObject,
FunctionWrapper,
NumberWrapper,
normalizeBool
} from 'angular2/src/facade/lang';
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
import {MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {ChangeDispatcher, DehydratedException, DynamicChangeDetector, ChangeDetectionError, BindingRecord, DirectiveRecord, DirectiveIndex, PipeTransform, ChangeDetectionStrategy, WrappedValue, DynamicProtoChangeDetector, ChangeDetectorDefinition, Lexer, Parser, Locals, ProtoChangeDetector} from 'angular2/src/core/change_detection/change_detection';
import {
ChangeDispatcher,
DehydratedException,
DynamicChangeDetector,
ChangeDetectionError,
BindingRecord,
DirectiveRecord,
DirectiveIndex,
PipeTransform,
ChangeDetectionStrategy,
WrappedValue,
DynamicProtoChangeDetector,
ChangeDetectorDefinition,
Lexer,
Parser,
Locals,
ProtoChangeDetector
} from 'angular2/src/core/change_detection/change_detection';
import {SelectedPipe, Pipes} from 'angular2/src/core/change_detection/pipes';
import {JitProtoChangeDetector} from 'angular2/src/core/change_detection/jit_proto_change_detector';
@@ -34,8 +71,8 @@ const _DEFAULT_CONTEXT = CONST_EXPR(new Object());
*/
export function main() {
['dynamic', 'JIT', 'Pregen'].forEach(cdType => {
if (cdType == 'JIT' && IS_DART) return;
if (cdType == 'Pregen' && !IS_DART) return;
if (cdType == "JIT" && IS_DART) return;
if (cdType == "Pregen" && !IS_DART) return;
describe(`${cdType} Change Detector`, () => {
@@ -61,8 +98,8 @@ export function main() {
}
function _createChangeDetector(
expression: string, context = _DEFAULT_CONTEXT, registry = null, dispatcher = null) {
function _createChangeDetector(expression: string, context = _DEFAULT_CONTEXT,
registry = null, dispatcher = null) {
if (isBlank(dispatcher)) dispatcher = new TestDispatcher();
var testDef = getDefinition(expression);
var cd = _getChangeDetectorFactory(testDef.cdDef)();
@@ -79,9 +116,8 @@ export function main() {
describe('short-circuit', () => {
it('should support short-circuit for the ternary operator', () => {
var address = new Address('Sunnyvale', '94085');
expect(_bindSimpleValue('true ? city : zipcode', address)).toEqual([
'propName=Sunnyvale'
]);
expect(_bindSimpleValue('true ? city : zipcode', address))
.toEqual(['propName=Sunnyvale']);
expect(address.cityGetterCalls).toEqual(1);
expect(address.zipCodeGetterCalls).toEqual(0);
@@ -376,7 +412,7 @@ export function main() {
var registry = new FakePipes('pipe', () => new MultiArgPipe());
var address = new Address('two');
var person = new Person('value', address);
var val = _createChangeDetector('name | pipe:\'one\':address.city', person, registry);
var val = _createChangeDetector("name | pipe:'one':address.city", person, registry);
val.changeDetector.detectChanges();
expect(val.dispatcher.loggedValues).toEqual(['value one two default']);
});
@@ -384,8 +420,7 @@ export function main() {
it('should associate pipes right-to-left', () => {
var registry = new FakePipes('pipe', () => new MultiArgPipe());
var person = new Person('value');
var val =
_createChangeDetector('name | pipe:\'a\':\'b\' | pipe:0:1:2', person, registry);
var val = _createChangeDetector("name | pipe:'a':'b' | pipe:0:1:2", person, registry);
val.changeDetector.detectChanges();
expect(val.dispatcher.loggedValues).toEqual(['value a b default 0 1 2']);
});
@@ -454,8 +489,8 @@ export function main() {
it('should happen directly, without invoking the dispatcher', () => {
var val = _createWithoutHydrate('directNoDispatcher');
val.changeDetector.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([directive1], []), null);
val.changeDetector.hydrate(_DEFAULT_CONTEXT, null, new TestDispatcher([directive1], []),
null);
val.changeDetector.detectChanges();
expect(val.dispatcher.loggedValues).toEqual([]);
expect(directive1.a).toEqual(42);
@@ -465,8 +500,8 @@ export function main() {
describe('ngOnChanges', () => {
it('should notify the directive when a group of records changes', () => {
var cd = _createWithoutHydrate('groupChanges').changeDetector;
cd.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []), null);
cd.hydrate(_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []),
null);
cd.detectChanges();
expect(directive1.changes).toEqual({'a': 1, 'b': 2});
expect(directive2.changes).toEqual({'a': 3});
@@ -502,8 +537,8 @@ export function main() {
it('should notify the directive after it has been checked the first time', () => {
var cd = _createWithoutHydrate('directiveOnInit').changeDetector;
cd.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []), null);
cd.hydrate(_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []),
null);
cd.detectChanges();
@@ -545,7 +580,7 @@ export function main() {
try {
cd.detectChanges();
} catch (e) {
throw new BaseException('Second detectChanges() should not have run detection.');
throw new BaseException("Second detectChanges() should not have run detection.");
}
expect(directive3.ngOnInitCalled).toBe(false);
});
@@ -554,8 +589,8 @@ export function main() {
describe('ngAfterContentInit', () => {
it('should be called after processing the content children', () => {
var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector;
cd.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []), null);
cd.hydrate(_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []),
null);
cd.detectChanges();
@@ -593,8 +628,8 @@ export function main() {
describe('ngAfterContentChecked', () => {
it('should be called after processing all the children', () => {
var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector;
cd.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []), null);
cd.hydrate(_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []),
null);
cd.detectChanges();
@@ -658,10 +693,10 @@ export function main() {
parentDirective =
new TestDirective(() => { orderOfOperations.push(parentDirective); });
parent.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([parentDirective], []), null);
child.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([directiveInShadowDom], []), null);
parent.hydrate(_DEFAULT_CONTEXT, null, new TestDispatcher([parentDirective], []),
null);
child.hydrate(_DEFAULT_CONTEXT, null,
new TestDispatcher([directiveInShadowDom], []), null);
parent.detectChanges();
expect(orderOfOperations).toEqual([parentDirective, directiveInShadowDom]);
@@ -672,8 +707,8 @@ export function main() {
describe('ngAfterViewInit', () => {
it('should be called after processing the view children', () => {
var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector;
cd.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []), null);
cd.hydrate(_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []),
null);
cd.detectChanges();
@@ -712,8 +747,8 @@ export function main() {
describe('ngAfterViewChecked', () => {
it('should be called after processing the view children', () => {
var cd = _createWithoutHydrate('emptyWithDirectiveRecords').changeDetector;
cd.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []), null);
cd.hydrate(_DEFAULT_CONTEXT, null, new TestDispatcher([directive1, directive2], []),
null);
cd.detectChanges();
@@ -777,10 +812,10 @@ export function main() {
parentDirective =
new TestDirective(null, () => { orderOfOperations.push(parentDirective); });
parent.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([parentDirective], []), null);
child.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([directiveInShadowDom], []), null);
parent.hydrate(_DEFAULT_CONTEXT, null, new TestDispatcher([parentDirective], []),
null);
child.hydrate(_DEFAULT_CONTEXT, null,
new TestDispatcher([directiveInShadowDom], []), null);
parent.detectChanges();
expect(orderOfOperations).toEqual([directiveInShadowDom, parentDirective]);
@@ -789,9 +824,8 @@ export function main() {
describe('ngOnDestroy', () => {
it('should be called on dehydration', () => {
var cd = _createChangeDetector(
'emptyWithDirectiveRecords', _DEFAULT_CONTEXT, null,
new TestDispatcher([directive1, directive2], []))
var cd = _createChangeDetector('emptyWithDirectiveRecords', _DEFAULT_CONTEXT, null,
new TestDispatcher([directive1, directive2], []))
.changeDetector;
cd.dehydrate();
@@ -806,7 +840,7 @@ export function main() {
});
});
describe('logBindingUpdate', () => {
describe("logBindingUpdate", () => {
it('should be called for element updates in the dev mode', () => {
var person = new Person('bob');
var val = _createChangeDetector('name', person);
@@ -815,11 +849,10 @@ export function main() {
});
it('should be called for directive updates in the dev mode', () => {
var val = _createChangeDetector(
'directNoDispatcher', _DEFAULT_CONTEXT, null,
new TestDispatcher([new TestDirective()], []));
var val = _createChangeDetector('directNoDispatcher', _DEFAULT_CONTEXT, null,
new TestDispatcher([new TestDirective()], []));
val.changeDetector.detectChanges();
expect(val.dispatcher.debugLog).toEqual(['a=42']);
expect(val.dispatcher.debugLog).toEqual(["a=42"]);
});
it('should not be called in the prod mode', () => {
@@ -836,8 +869,8 @@ export function main() {
var directive = new TestDirective();
directive.a = 'aaa';
var val = _createChangeDetector(
'readingDirectives', _DEFAULT_CONTEXT, null, new TestDispatcher([directive], []));
var val = _createChangeDetector('readingDirectives', _DEFAULT_CONTEXT, null,
new TestDispatcher([directive], []));
val.changeDetector.detectChanges();
@@ -885,9 +918,8 @@ export function main() {
it('should handle unexpected errors in the event handler itself', () => {
var throwingDispatcher = new SpyChangeDispatcher();
throwingDispatcher.spy('getDebugContext').andCallFake((_, __) => {
throw new BaseException('boom');
});
throwingDispatcher.spy("getDebugContext")
.andCallFake((_, __) => { throw new BaseException('boom'); });
var val =
_createChangeDetector('invalidFn(1)', _DEFAULT_CONTEXT, null, throwingDispatcher);
@@ -914,21 +946,18 @@ export function main() {
it('should fall back to a regular field read when the locals map' +
'does not have the requested field',
() => {
expect(_bindSimpleValue('fallbackLocals', new Person('Jim'))).toEqual([
'propName=Jim'
]);
expect(_bindSimpleValue('fallbackLocals', new Person('Jim')))
.toEqual(['propName=Jim']);
});
it('should correctly handle nested properties', () => {
var address = new Address('Grenoble');
var person = new Person('Victor', address);
expect(_bindSimpleValue('contextNestedPropertyWithLocals', person)).toEqual([
'propName=Grenoble'
]);
expect(_bindSimpleValue('localPropertyWithSimilarContext', person)).toEqual([
'propName=MTV'
]);
expect(_bindSimpleValue('contextNestedPropertyWithLocals', person))
.toEqual(['propName=Grenoble']);
expect(_bindSimpleValue('localPropertyWithSimilarContext', person))
.toEqual(['propName=MTV']);
});
});
@@ -1038,9 +1067,9 @@ export function main() {
childDirectiveDetectorOnPush.hydrate(_DEFAULT_CONTEXT, null, null, null);
childDirectiveDetectorOnPush.mode = ChangeDetectionStrategy.Checked;
directives = new TestDispatcher(
[new TestData(null), new TestData(null)],
[childDirectiveDetectorRegular, childDirectiveDetectorOnPush]);
directives =
new TestDispatcher([new TestData(null), new TestData(null)],
[childDirectiveDetectorRegular, childDirectiveDetectorOnPush]);
});
it('should set the mode to CheckOnce when a binding is updated', () => {
@@ -1061,7 +1090,7 @@ export function main() {
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
cd.mode = ChangeDetectionStrategy.Checked;
cd.handleEvent('event', 0, null);
cd.handleEvent("event", 0, null);
expect(cd.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
});
@@ -1070,7 +1099,7 @@ export function main() {
var cd = _createWithoutHydrate('onPushWithHostEvent').changeDetector;
cd.hydrate(_DEFAULT_CONTEXT, null, directives, null);
cd.handleEvent('host-event', 0, null);
cd.handleEvent("host-event", 0, null);
expect(childDirectiveDetectorOnPush.mode).toEqual(ChangeDetectionStrategy.CheckOnce);
});
@@ -1148,7 +1177,7 @@ export function main() {
val.changeDetector.dehydrate();
expect(() => {val.changeDetector.detectChanges()})
.toThrowErrorWith('Attempt to use a dehydrated detector');
.toThrowErrorWith("Attempt to use a dehydrated detector");
expect(val.dispatcher.log).toEqual(['propName=Bob']);
});
});
@@ -1185,42 +1214,42 @@ export function main() {
var d: TestDirective;
beforeEach(() => {
event = 'EVENT';
event = "EVENT";
d = new TestDirective();
});
it('should execute events', () => {
var val = _createChangeDetector('(event)="onEvent($event)"', d, null);
val.changeDetector.handleEvent('event', 0, event);
expect(d.event).toEqual('EVENT');
val.changeDetector.handleEvent("event", 0, event);
expect(d.event).toEqual("EVENT");
});
it('should execute host events', () => {
var val = _createWithoutHydrate('(host-event)="onEvent($event)"');
val.changeDetector.hydrate(
_DEFAULT_CONTEXT, null, new TestDispatcher([d, new TestDirective()], []), null);
val.changeDetector.handleEvent('host-event', 0, event);
expect(d.event).toEqual('EVENT');
val.changeDetector.hydrate(_DEFAULT_CONTEXT, null,
new TestDispatcher([d, new TestDirective()], []), null);
val.changeDetector.handleEvent("host-event", 0, event);
expect(d.event).toEqual("EVENT");
});
it('should support field assignments', () => {
var val = _createChangeDetector('(event)="b=a=$event"', d, null);
val.changeDetector.handleEvent('event', 0, event);
expect(d.a).toEqual('EVENT');
expect(d.b).toEqual('EVENT');
val.changeDetector.handleEvent("event", 0, event);
expect(d.a).toEqual("EVENT");
expect(d.b).toEqual("EVENT");
});
it('should support keyed assignments', () => {
d.a = ['OLD'];
d.a = ["OLD"];
var val = _createChangeDetector('(event)="a[0]=$event"', d, null);
val.changeDetector.handleEvent('event', 0, event);
expect(d.a).toEqual(['EVENT']);
val.changeDetector.handleEvent("event", 0, event);
expect(d.a).toEqual(["EVENT"]);
});
it('should support chains', () => {
d.a = 0;
var val = _createChangeDetector('(event)="a=a+1; a=a+1;"', d, null);
val.changeDetector.handleEvent('event', 0, event);
val.changeDetector.handleEvent("event", 0, event);
expect(d.a).toEqual(2);
});
@@ -1233,22 +1262,22 @@ export function main() {
it('should return false if the event handler returned false', () => {
var val = _createChangeDetector('(event)="false"', d, null);
var res = val.changeDetector.handleEvent('event', 0, event);
var res = val.changeDetector.handleEvent("event", 0, event);
expect(res).toBe(false);
val = _createChangeDetector('(event)="true"', d, null);
res = val.changeDetector.handleEvent('event', 0, event);
res = val.changeDetector.handleEvent("event", 0, event);
expect(res).toBe(true);
val = _createChangeDetector('(event)="true; false"', d, null);
res = val.changeDetector.handleEvent('event', 0, event);
res = val.changeDetector.handleEvent("event", 0, event);
expect(res).toBe(false);
});
it('should support short-circuiting', () => {
d.a = 0;
var val = _createChangeDetector('(event)="true ? a = a + 1 : a = a + 1"', d, null);
val.changeDetector.handleEvent('event', 0, event);
val.changeDetector.handleEvent("event", 0, event);
expect(d.a).toEqual(1);
});
});
@@ -1258,9 +1287,8 @@ export function main() {
it('should call handleEvent when an output of a directive fires', fakeAsync(() => {
var directive1 = new TestDirective();
var directive2 = new TestDirective();
_createChangeDetector(
'(host-event)="onEvent(\$event)"', new Object(), null,
new TestDispatcher([directive1, directive2]));
_createChangeDetector('(host-event)="onEvent(\$event)"', new Object(), null,
new TestDispatcher([directive1, directive2]));
ObservableWrapper.callEmit(directive2.eventEmitter, 'EVENT');
tick();
@@ -1271,9 +1299,8 @@ export function main() {
it('should ignore events when dehydrated', fakeAsync(() => {
var directive1 = new TestDirective();
var directive2 = new TestDirective();
var cd = _createChangeDetector(
'(host-event)="onEvent(\$event)"', new Object(), null,
new TestDispatcher([directive1, directive2]))
var cd = _createChangeDetector('(host-event)="onEvent(\$event)"', new Object(), null,
new TestDispatcher([directive1, directive2]))
.changeDetector;
cd.dehydrate();
ObservableWrapper.callEmit(directive2.eventEmitter, 'EVENT');
@@ -1378,9 +1405,8 @@ class TestDirective {
event;
eventEmitter: EventEmitter<string> = new EventEmitter<string>();
constructor(
public ngAfterContentCheckedSpy = null, public ngAfterViewCheckedSpy = null,
public throwOnInit = false) {}
constructor(public ngAfterContentCheckedSpy = null, public ngAfterViewCheckedSpy = null,
public throwOnInit = false) {}
onEvent(event) { this.event = event; }
@@ -1389,7 +1415,7 @@ class TestDirective {
ngOnInit() {
this.ngOnInitCalled = true;
if (this.throwOnInit) {
throw 'simulated ngOnInit failure';
throw "simulated ngOnInit failure";
}
}
@@ -1495,8 +1521,8 @@ class TestDispatcher implements ChangeDispatcher {
ngAfterViewCheckedCalled: boolean = false;
ngOnDestroyCalled: boolean = false;
constructor(
public directives: Array<TestData|TestDirective> = null, public detectors: any[] = null) {
constructor(public directives: Array<TestData | TestDirective> = null,
public detectors: any[] = null) {
if (isBlank(this.directives)) {
this.directives = [];
}
@@ -1,11 +1,20 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {ChangeDetectionUtil} from 'angular2/src/core/change_detection/change_detection_util';
export function main() {
describe('ChangeDetectionUtil', () => {
describe('devModeEqual', () => {
it('should do the deep comparison of iterables', () => {
describe("ChangeDetectionUtil", () => {
describe("devModeEqual", () => {
it("should do the deep comparison of iterables", () => {
expect(ChangeDetectionUtil.devModeEqual([['one']], [['one']])).toBe(true);
expect(ChangeDetectionUtil.devModeEqual(['one'], ['one', 'two'])).toBe(false);
expect(ChangeDetectionUtil.devModeEqual(['one', 'two'], ['one'])).toBe(false);
@@ -15,35 +24,35 @@ export function main() {
expect(ChangeDetectionUtil.devModeEqual(new Object(), ['one'])).toBe(false);
});
it('should compare primitive numbers', () => {
it("should compare primitive numbers", () => {
expect(ChangeDetectionUtil.devModeEqual(1, 1)).toBe(true);
expect(ChangeDetectionUtil.devModeEqual(1, 2)).toBe(false);
expect(ChangeDetectionUtil.devModeEqual(new Object(), 2)).toBe(false);
expect(ChangeDetectionUtil.devModeEqual(1, new Object())).toBe(false);
});
it('should compare primitive strings', () => {
it("should compare primitive strings", () => {
expect(ChangeDetectionUtil.devModeEqual('one', 'one')).toBe(true);
expect(ChangeDetectionUtil.devModeEqual('one', 'two')).toBe(false);
expect(ChangeDetectionUtil.devModeEqual(new Object(), 'one')).toBe(false);
expect(ChangeDetectionUtil.devModeEqual('one', new Object())).toBe(false);
});
it('should compare primitive booleans', () => {
it("should compare primitive booleans", () => {
expect(ChangeDetectionUtil.devModeEqual(true, true)).toBe(true);
expect(ChangeDetectionUtil.devModeEqual(true, false)).toBe(false);
expect(ChangeDetectionUtil.devModeEqual(new Object(), true)).toBe(false);
expect(ChangeDetectionUtil.devModeEqual(true, new Object())).toBe(false);
});
it('should compare null', () => {
it("should compare null", () => {
expect(ChangeDetectionUtil.devModeEqual(null, null)).toBe(true);
expect(ChangeDetectionUtil.devModeEqual(null, 1)).toBe(false);
expect(ChangeDetectionUtil.devModeEqual(new Object(), null)).toBe(false);
expect(ChangeDetectionUtil.devModeEqual(null, new Object())).toBe(false);
});
it('should return true for other objects', () => {
it("should return true for other objects", () => {
expect(ChangeDetectionUtil.devModeEqual(new Object(), new Object())).toBe(true);
});
});
@@ -1,4 +1,13 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {isBlank} from 'angular2/src/facade/lang';
import {coalesce} from 'angular2/src/core/change_detection/coalesce';
@@ -6,91 +15,92 @@ import {RecordType, ProtoRecord} from 'angular2/src/core/change_detection/proto_
import {DirectiveIndex} from 'angular2/src/core/change_detection/directive_record';
export function main() {
function r(
funcOrValue, args, contextIndex, selfIndex,
{lastInBinding, mode, name, directiveIndex, argumentToPureFunction, fixedArgs}: {
lastInBinding?: any,
mode?: any,
name?: any,
directiveIndex?: any,
argumentToPureFunction?: boolean,
fixedArgs?: any[]
} = {}) {
function r(funcOrValue, args, contextIndex, selfIndex,
{lastInBinding, mode, name, directiveIndex, argumentToPureFunction, fixedArgs}: {
lastInBinding?: any,
mode?: any,
name?: any,
directiveIndex?: any,
argumentToPureFunction?: boolean,
fixedArgs?: any[]
} = {}) {
if (isBlank(lastInBinding)) lastInBinding = false;
if (isBlank(mode)) mode = RecordType.PropertyRead;
if (isBlank(name)) name = 'name';
if (isBlank(name)) name = "name";
if (isBlank(directiveIndex)) directiveIndex = null;
if (isBlank(argumentToPureFunction)) argumentToPureFunction = false;
if (isBlank(fixedArgs)) fixedArgs = null;
return new ProtoRecord(
mode, name, funcOrValue, args, fixedArgs, contextIndex, directiveIndex, selfIndex, null,
lastInBinding, false, argumentToPureFunction, false, 0);
return new ProtoRecord(mode, name, funcOrValue, args, fixedArgs, contextIndex, directiveIndex,
selfIndex, null, lastInBinding, false, argumentToPureFunction, false, 0);
}
describe('change detection - coalesce', () => {
it('should work with an empty list', () => { expect(coalesce([])).toEqual([]); });
describe("change detection - coalesce", () => {
it("should work with an empty list", () => { expect(coalesce([])).toEqual([]); });
it('should remove non-terminal duplicate records and update the context indices referencing them',
it("should remove non-terminal duplicate records and update the context indices referencing them",
() => {
var rs = coalesce(
[r('user', [], 0, 1), r('first', [], 1, 2), r('user', [], 0, 3), r('last', [], 3, 4)]);
[r("user", [], 0, 1), r("first", [], 1, 2), r("user", [], 0, 3), r("last", [], 3, 4)]);
expect(rs).toEqual([r('user', [], 0, 1), r('first', [], 1, 2), r('last', [], 1, 3)]);
expect(rs).toEqual([r("user", [], 0, 1), r("first", [], 1, 2), r("last", [], 1, 3)]);
});
it('should update indices of other records', () => {
it("should update indices of other records", () => {
var rs = coalesce(
[r('dup', [], 0, 1), r('dup', [], 0, 2), r('user', [], 0, 3), r('first', [3], 3, 4)]);
[r("dup", [], 0, 1), r("dup", [], 0, 2), r("user", [], 0, 3), r("first", [3], 3, 4)]);
expect(rs).toEqual([r('dup', [], 0, 1), r('user', [], 0, 2), r('first', [2], 2, 3)]);
expect(rs).toEqual([r("dup", [], 0, 1), r("user", [], 0, 2), r("first", [2], 2, 3)]);
});
it('should remove non-terminal duplicate records and update the args indices referencing them',
it("should remove non-terminal duplicate records and update the args indices referencing them",
() => {
var rs = coalesce([
r('user1', [], 0, 1), r('user2', [], 0, 2), r('hi', [1], 0, 3), r('hi', [1], 0, 4),
r('hi', [2], 0, 5)
r("user1", [], 0, 1),
r("user2", [], 0, 2),
r("hi", [1], 0, 3),
r("hi", [1], 0, 4),
r("hi", [2], 0, 5)
]);
expect(rs).toEqual(
[r('user1', [], 0, 1), r('user2', [], 0, 2), r('hi', [1], 0, 3), r('hi', [2], 0, 4)]);
[r("user1", [], 0, 1), r("user2", [], 0, 2), r("hi", [1], 0, 3), r("hi", [2], 0, 4)]);
});
it('should replace duplicate terminal records with self records', () => {
it("should replace duplicate terminal records with self records", () => {
var rs = coalesce(
[r('user', [], 0, 1, {lastInBinding: true}), r('user', [], 0, 2, {lastInBinding: true})]);
[r("user", [], 0, 1, {lastInBinding: true}), r("user", [], 0, 2, {lastInBinding: true})]);
expect(rs[1]).toEqual(new ProtoRecord(
RecordType.Self, 'self', null, [], null, 1, null, 2, null, true, false, false, false, 0));
expect(rs[1]).toEqual(new ProtoRecord(RecordType.Self, "self", null, [], null, 1, null, 2,
null, true, false, false, false, 0));
});
it('should set referencedBySelf', () => {
it("should set referencedBySelf", () => {
var rs = coalesce(
[r('user', [], 0, 1, {lastInBinding: true}), r('user', [], 0, 2, {lastInBinding: true})]);
[r("user", [], 0, 1, {lastInBinding: true}), r("user", [], 0, 2, {lastInBinding: true})]);
expect(rs[0].referencedBySelf).toBeTruthy();
});
it('should not coalesce directive lifecycle records', () => {
it("should not coalesce directive lifecycle records", () => {
var rs = coalesce([
r('ngDoCheck', [], 0, 1, {mode: RecordType.DirectiveLifecycle}),
r('ngDoCheck', [], 0, 1, {mode: RecordType.DirectiveLifecycle})
r("ngDoCheck", [], 0, 1, {mode: RecordType.DirectiveLifecycle}),
r("ngDoCheck", [], 0, 1, {mode: RecordType.DirectiveLifecycle})
]);
expect(rs.length).toEqual(2);
});
it('should not coalesce protos with different names but same value', () => {
it("should not coalesce protos with different names but same value", () => {
var nullFunc = () => {};
var rs = coalesce([
r(nullFunc, [], 0, 1, {name: 'foo'}),
r(nullFunc, [], 0, 1, {name: 'bar'}),
r(nullFunc, [], 0, 1, {name: "foo"}),
r(nullFunc, [], 0, 1, {name: "bar"}),
]);
expect(rs.length).toEqual(2);
});
it('should not coalesce protos with the same context index but different directive indices',
it("should not coalesce protos with the same context index but different directive indices",
() => {
var nullFunc = () => {};
var rs = coalesce([
@@ -104,32 +114,35 @@ export function main() {
it('should preserve the argumentToPureFunction property', () => {
var rs = coalesce([
r('user', [], 0, 1), r('user', [], 0, 2, {argumentToPureFunction: true}),
r('user', [], 0, 3), r('name', [], 3, 4)
r("user", [], 0, 1),
r("user", [], 0, 2, {argumentToPureFunction: true}),
r("user", [], 0, 3),
r("name", [], 3, 4)
]);
expect(rs).toEqual(
[r('user', [], 0, 1, {argumentToPureFunction: true}), r('name', [], 1, 2)]);
expect(rs)
.toEqual([r("user", [], 0, 1, {argumentToPureFunction: true}), r("name", [], 1, 2)]);
});
it('should preserve the argumentToPureFunction property (the original record)', () => {
var rs = coalesce([
r('user', [], 0, 1, {argumentToPureFunction: true}), r('user', [], 0, 2),
r('name', [], 2, 3)
r("user", [], 0, 1, {argumentToPureFunction: true}),
r("user", [], 0, 2),
r("name", [], 2, 3)
]);
expect(rs).toEqual(
[r('user', [], 0, 1, {argumentToPureFunction: true}), r('name', [], 1, 2)]);
expect(rs)
.toEqual([r("user", [], 0, 1, {argumentToPureFunction: true}), r("name", [], 1, 2)]);
});
describe('short-circuit', () => {
it('should not use short-circuitable records', () => {
var records = [
r('sknot', [], 0, 1, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [3]}),
r('a', [], 0, 2),
r('sk', [], 0, 3, {mode: RecordType.SkipRecords, fixedArgs: [4]}),
r('b', [], 0, 4),
r('cond', [2, 4], 0, 5),
r('a', [], 0, 6),
r('b', [], 0, 7),
r("sknot", [], 0, 1, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [3]}),
r("a", [], 0, 2),
r("sk", [], 0, 3, {mode: RecordType.SkipRecords, fixedArgs: [4]}),
r("b", [], 0, 4),
r("cond", [2, 4], 0, 5),
r("a", [], 0, 6),
r("b", [], 0, 7),
];
expect(coalesce(records)).toEqual(records);
@@ -137,18 +150,18 @@ export function main() {
it('should not use short-circuitable records from nested short-circuits', () => {
var records = [
r('sknot outer', [], 0, 1, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [7]}),
r('sknot inner', [], 0, 2, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [4]}),
r('a', [], 0, 3),
r('sk inner', [], 0, 4, {mode: RecordType.SkipRecords, fixedArgs: [5]}),
r('b', [], 0, 5),
r('cond-inner', [3, 5], 0, 6),
r('sk outer', [], 0, 7, {mode: RecordType.SkipRecords, fixedArgs: [8]}),
r('c', [], 0, 8),
r('cond-outer', [6, 8], 0, 9),
r('a', [], 0, 10),
r('b', [], 0, 11),
r('c', [], 0, 12),
r("sknot outer", [], 0, 1, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [7]}),
r("sknot inner", [], 0, 2, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [4]}),
r("a", [], 0, 3),
r("sk inner", [], 0, 4, {mode: RecordType.SkipRecords, fixedArgs: [5]}),
r("b", [], 0, 5),
r("cond-inner", [3, 5], 0, 6),
r("sk outer", [], 0, 7, {mode: RecordType.SkipRecords, fixedArgs: [8]}),
r("c", [], 0, 8),
r("cond-outer", [6, 8], 0, 9),
r("a", [], 0, 10),
r("b", [], 0, 11),
r("c", [], 0, 12),
];
expect(coalesce(records)).toEqual(records);
@@ -156,65 +169,65 @@ export function main() {
it('should collapse the true branch', () => {
var rs = coalesce([
r('a', [], 0, 1),
r('sknot', [], 0, 2, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [4]}),
r('a', [], 0, 3),
r('sk', [], 0, 4, {mode: RecordType.SkipRecords, fixedArgs: [6]}),
r('a', [], 0, 5),
r('b', [], 5, 6),
r('cond', [3, 6], 0, 7),
r("a", [], 0, 1),
r("sknot", [], 0, 2, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [4]}),
r("a", [], 0, 3),
r("sk", [], 0, 4, {mode: RecordType.SkipRecords, fixedArgs: [6]}),
r("a", [], 0, 5),
r("b", [], 5, 6),
r("cond", [3, 6], 0, 7),
]);
expect(rs).toEqual([
r('a', [], 0, 1),
r('sknot', [], 0, 2, {mode: RecordType.SkipRecordsIf, fixedArgs: [3]}),
r('b', [], 1, 3),
r('cond', [1, 3], 0, 4),
r("a", [], 0, 1),
r("sknot", [], 0, 2, {mode: RecordType.SkipRecordsIf, fixedArgs: [3]}),
r("b", [], 1, 3),
r("cond", [1, 3], 0, 4),
]);
});
it('should collapse the false branch', () => {
var rs = coalesce([
r('a', [], 0, 1),
r('sknot', [], 0, 2, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [5]}),
r('a', [], 0, 3),
r('b', [], 3, 4),
r('sk', [], 0, 5, {mode: RecordType.SkipRecords, fixedArgs: [6]}),
r('a', [], 0, 6),
r('cond', [4, 6], 0, 7),
r("a", [], 0, 1),
r("sknot", [], 0, 2, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [5]}),
r("a", [], 0, 3),
r("b", [], 3, 4),
r("sk", [], 0, 5, {mode: RecordType.SkipRecords, fixedArgs: [6]}),
r("a", [], 0, 6),
r("cond", [4, 6], 0, 7),
]);
expect(rs).toEqual([
r('a', [], 0, 1),
r('sknot', [], 0, 2, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [3]}),
r('b', [], 1, 3),
r('cond', [3, 1], 0, 4),
r("a", [], 0, 1),
r("sknot", [], 0, 2, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [3]}),
r("b", [], 1, 3),
r("cond", [3, 1], 0, 4),
]);
});
it('should optimize skips', () => {
var rs = coalesce([
// skipIfNot(1) + skip(N) -> skipIf(+N)
r('sknot', [], 0, 1, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [2]}),
r('sk', [], 0, 2, {mode: RecordType.SkipRecords, fixedArgs: [3]}),
r('a', [], 0, 3),
r("sknot", [], 0, 1, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [2]}),
r("sk", [], 0, 2, {mode: RecordType.SkipRecords, fixedArgs: [3]}),
r("a", [], 0, 3),
// skipIf(1) + skip(N) -> skipIfNot(N)
r('skif', [], 0, 4, {mode: RecordType.SkipRecordsIf, fixedArgs: [5]}),
r('sk', [], 0, 5, {mode: RecordType.SkipRecords, fixedArgs: [6]}),
r('b', [], 0, 6),
r("skif", [], 0, 4, {mode: RecordType.SkipRecordsIf, fixedArgs: [5]}),
r("sk", [], 0, 5, {mode: RecordType.SkipRecords, fixedArgs: [6]}),
r("b", [], 0, 6),
// remove empty skips
r('sknot', [], 0, 7, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [7]}),
r('skif', [], 0, 8, {mode: RecordType.SkipRecordsIf, fixedArgs: [8]}),
r('sk', [], 0, 9, {mode: RecordType.SkipRecords, fixedArgs: [9]}),
r('end', [], 0, 10),
r("sknot", [], 0, 7, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [7]}),
r("skif", [], 0, 8, {mode: RecordType.SkipRecordsIf, fixedArgs: [8]}),
r("sk", [], 0, 9, {mode: RecordType.SkipRecords, fixedArgs: [9]}),
r("end", [], 0, 10),
]);
expect(rs).toEqual([
r('sknot', [], 0, 1, {mode: RecordType.SkipRecordsIf, fixedArgs: [2]}),
r('a', [], 0, 2),
r('skif', [], 0, 3, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [4]}),
r('b', [], 0, 4),
r('end', [], 0, 5),
r("sknot", [], 0, 1, {mode: RecordType.SkipRecordsIf, fixedArgs: [2]}),
r("a", [], 0, 2),
r("skif", [], 0, 3, {mode: RecordType.SkipRecordsIfNot, fixedArgs: [4]}),
r("b", [], 0, 4),
r("end", [], 0, 5),
]);
});
});
@@ -1,5 +1,17 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {DefaultIterableDiffer, DefaultIterableDifferFactory} from 'angular2/src/core/change_detection/differs/default_iterable_differ';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {
DefaultIterableDiffer,
DefaultIterableDifferFactory
} from 'angular2/src/core/change_detection/differs/default_iterable_differ';
import {NumberWrapper} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection';
@@ -42,19 +54,19 @@ export function main() {
l.list = [1];
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['1[null->0]'],
additions: ['1[null->0]']
}));
expect(differ.toString())
.toEqual(
iterableChangesAsString({collection: ['1[null->0]'], additions: ['1[null->0]']}));
l.list = [2, 1];
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['2[null->0]', '1[0->1]'],
previous: ['1[0->1]'],
additions: ['2[null->0]'],
moves: ['1[0->1]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['2[null->0]', '1[0->1]'],
previous: ['1[0->1]'],
additions: ['2[null->0]'],
moves: ['1[0->1]']
}));
});
it('should detect additions', () => {
@@ -64,10 +76,9 @@ export function main() {
l.push('a');
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['a[null->0]'],
additions: ['a[null->0]']
}));
expect(differ.toString())
.toEqual(
iterableChangesAsString({collection: ['a[null->0]'], additions: ['a[null->0]']}));
l.push('b');
differ.check(l);
@@ -82,21 +93,23 @@ export function main() {
l = [1, 0];
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['1[null->0]', '0[0->1]'],
previous: ['0[0->1]'],
additions: ['1[null->0]'],
moves: ['0[0->1]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['1[null->0]', '0[0->1]'],
previous: ['0[0->1]'],
additions: ['1[null->0]'],
moves: ['0[0->1]']
}));
l = [2, 1, 0];
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['2[null->0]', '1[0->1]', '0[1->2]'],
previous: ['1[0->1]', '0[1->2]'],
additions: ['2[null->0]'],
moves: ['1[0->1]', '0[1->2]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['2[null->0]', '1[0->1]', '0[1->2]'],
previous: ['1[0->1]', '0[1->2]'],
additions: ['2[null->0]'],
moves: ['1[0->1]', '0[1->2]']
}));
});
it('should handle swapping element', () => {
@@ -107,11 +120,12 @@ export function main() {
l.push(2);
l.push(1);
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['2[1->0]', '1[0->1]'],
previous: ['1[0->1]', '2[1->0]'],
moves: ['2[1->0]', '1[0->1]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['2[1->0]', '1[0->1]'],
previous: ['1[0->1]', '2[1->0]'],
moves: ['2[1->0]', '1[0->1]']
}));
});
it('should handle incremental swapping element', () => {
@@ -121,20 +135,22 @@ export function main() {
ListWrapper.removeAt(l, 1);
ListWrapper.insert(l, 0, 'b');
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['b[1->0]', 'a[0->1]', 'c'],
previous: ['a[0->1]', 'b[1->0]', 'c'],
moves: ['b[1->0]', 'a[0->1]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['b[1->0]', 'a[0->1]', 'c'],
previous: ['a[0->1]', 'b[1->0]', 'c'],
moves: ['b[1->0]', 'a[0->1]']
}));
ListWrapper.removeAt(l, 1);
l.push('a');
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['b', 'c[2->1]', 'a[1->2]'],
previous: ['b', 'a[1->2]', 'c[2->1]'],
moves: ['c[2->1]', 'a[1->2]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['b', 'c[2->1]', 'a[1->2]'],
previous: ['b', 'a[1->2]', 'c[2->1]'],
moves: ['c[2->1]', 'a[1->2]']
}));
});
it('should detect changes in list', () => {
@@ -143,10 +159,9 @@ export function main() {
l.push('a');
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['a[null->0]'],
additions: ['a[null->0]']
}));
expect(differ.toString())
.toEqual(
iterableChangesAsString({collection: ['a[null->0]'], additions: ['a[null->0]']}));
l.push('b');
differ.check(l);
@@ -157,20 +172,22 @@ export function main() {
l.push('c');
l.push('d');
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['a', 'b', 'c[null->2]', 'd[null->3]'],
previous: ['a', 'b'],
additions: ['c[null->2]', 'd[null->3]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['a', 'b', 'c[null->2]', 'd[null->3]'],
previous: ['a', 'b'],
additions: ['c[null->2]', 'd[null->3]']
}));
ListWrapper.removeAt(l, 2);
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['a', 'b', 'd[3->2]'],
previous: ['a', 'b', 'c[2->null]', 'd[3->2]'],
moves: ['d[3->2]'],
removals: ['c[2->null]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['a', 'b', 'd[3->2]'],
previous: ['a', 'b', 'c[2->null]', 'd[3->2]'],
moves: ['d[3->2]'],
removals: ['c[2->null]']
}));
ListWrapper.clear(l);
l.push('d');
@@ -178,12 +195,13 @@ export function main() {
l.push('b');
l.push('a');
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['d[2->0]', 'c[null->1]', 'b[1->2]', 'a[0->3]'],
previous: ['a[0->3]', 'b[1->2]', 'd[2->0]'],
additions: ['c[null->1]'],
moves: ['d[2->0]', 'b[1->2]', 'a[0->3]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['d[2->0]', 'c[null->1]', 'b[1->2]', 'a[0->3]'],
previous: ['a[0->3]', 'b[1->2]', 'd[2->0]'],
additions: ['c[null->1]'],
moves: ['d[2->0]', 'b[1->2]', 'a[0->3]']
}));
});
it('should test string by value rather than by reference (Dart)', () => {
@@ -202,10 +220,9 @@ export function main() {
let l = [NumberWrapper.NaN];
differ.check(l);
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: [NumberWrapper.NaN],
previous: [NumberWrapper.NaN]
}));
expect(differ.toString())
.toEqual(iterableChangesAsString(
{collection: [NumberWrapper.NaN], previous: [NumberWrapper.NaN]}));
});
it('should detect [NaN] moves', () => {
@@ -214,12 +231,13 @@ export function main() {
ListWrapper.insert<any>(l, 0, 'foo');
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['foo[null->0]', 'NaN[0->1]', 'NaN[1->2]'],
previous: ['NaN[0->1]', 'NaN[1->2]'],
additions: ['foo[null->0]'],
moves: ['NaN[0->1]', 'NaN[1->2]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['foo[null->0]', 'NaN[0->1]', 'NaN[1->2]'],
previous: ['NaN[0->1]', 'NaN[1->2]'],
additions: ['foo[null->0]'],
moves: ['NaN[0->1]', 'NaN[1->2]']
}));
});
it('should remove and add same item', () => {
@@ -228,21 +246,23 @@ export function main() {
ListWrapper.removeAt(l, 1);
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['a', 'c[2->1]'],
previous: ['a', 'b[1->null]', 'c[2->1]'],
moves: ['c[2->1]'],
removals: ['b[1->null]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['a', 'c[2->1]'],
previous: ['a', 'b[1->null]', 'c[2->1]'],
moves: ['c[2->1]'],
removals: ['b[1->null]']
}));
ListWrapper.insert(l, 1, 'b');
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['a', 'b[null->1]', 'c[1->2]'],
previous: ['a', 'c[1->2]'],
additions: ['b[null->1]'],
moves: ['c[1->2]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['a', 'b[null->1]', 'c[1->2]'],
previous: ['a', 'c[1->2]'],
additions: ['b[null->1]'],
moves: ['c[1->2]']
}));
});
@@ -252,12 +272,13 @@ export function main() {
ListWrapper.removeAt(l, 0);
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['a', 'a', 'b[3->2]', 'b[4->3]'],
previous: ['a', 'a', 'a[2->null]', 'b[3->2]', 'b[4->3]'],
moves: ['b[3->2]', 'b[4->3]'],
removals: ['a[2->null]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['a', 'a', 'b[3->2]', 'b[4->3]'],
previous: ['a', 'a', 'a[2->null]', 'b[3->2]', 'b[4->3]'],
moves: ['b[3->2]', 'b[4->3]'],
removals: ['a[2->null]']
}));
});
it('should support insertions/moves', () => {
@@ -266,12 +287,13 @@ export function main() {
ListWrapper.insert(l, 0, 'b');
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['b[2->0]', 'a[0->1]', 'a[1->2]', 'b', 'b[null->4]'],
previous: ['a[0->1]', 'a[1->2]', 'b[2->0]', 'b'],
additions: ['b[null->4]'],
moves: ['b[2->0]', 'a[0->1]', 'a[1->2]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['b[2->0]', 'a[0->1]', 'a[1->2]', 'b', 'b[null->4]'],
previous: ['a[0->1]', 'a[1->2]', 'b[2->0]', 'b'],
additions: ['b[null->4]'],
moves: ['b[2->0]', 'a[0->1]', 'a[1->2]']
}));
});
it('should not report unnecessary moves', () => {
@@ -283,11 +305,12 @@ export function main() {
l.push('a');
l.push('c');
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['b[1->0]', 'a[0->1]', 'c'],
previous: ['a[0->1]', 'b[1->0]', 'c'],
moves: ['b[1->0]', 'a[0->1]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['b[1->0]', 'a[0->1]', 'c'],
previous: ['a[0->1]', 'b[1->0]', 'c'],
moves: ['b[1->0]', 'a[0->1]']
}));
});
it('should not diff immutable collections if they are the same', () => {
@@ -302,10 +325,9 @@ export function main() {
differ.check(l1);
expect(trackByCount).toBe(1);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['1[null->0]'],
additions: ['1[null->0]']
}));
expect(differ.toString())
.toEqual(
iterableChangesAsString({collection: ['1[null->0]'], additions: ['1[null->0]']}));
trackByCount = 0;
@@ -322,9 +344,8 @@ export function main() {
});
describe('diff', () => {
it('should return self when there is a change', () => {
expect(differ.diff(['a', 'b'])).toBe(differ);
});
it('should return self when there is a change',
() => { expect(differ.diff(['a', 'b'])).toBe(differ); });
it('should return null when there is no change', () => {
differ.diff(['a', 'b']);
@@ -333,14 +354,15 @@ export function main() {
it('should treat null as an empty list', () => {
differ.diff(['a', 'b']);
expect(differ.diff(null).toString()).toEqual(iterableChangesAsString({
previous: ['a[0->null]', 'b[1->null]'],
removals: ['a[0->null]', 'b[1->null]']
}));
expect(differ.diff(null).toString())
.toEqual(iterableChangesAsString({
previous: ['a[0->null]', 'b[1->null]'],
removals: ['a[0->null]', 'b[1->null]']
}));
});
it('should throw when given an invalid collection', () => {
expect(() => differ.diff('invalid')).toThrowErrorWith('Error trying to diff \'invalid\'');
expect(() => differ.diff("invalid")).toThrowErrorWith("Error trying to diff 'invalid'");
});
});
});
@@ -363,18 +385,20 @@ export function main() {
it('should treat seen records as identity changes, not additions', () => {
let l = buildItemList(['a', 'b', 'c']);
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: [`{id: a}[null->0]`, `{id: b}[null->1]`, `{id: c}[null->2]`],
additions: [`{id: a}[null->0]`, `{id: b}[null->1]`, `{id: c}[null->2]`]
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: [`{id: a}[null->0]`, `{id: b}[null->1]`, `{id: c}[null->2]`],
additions: [`{id: a}[null->0]`, `{id: b}[null->1]`, `{id: c}[null->2]`]
}));
l = buildItemList(['a', 'b', 'c']);
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: [`{id: a}`, `{id: b}`, `{id: c}`],
identityChanges: [`{id: a}`, `{id: b}`, `{id: c}`],
previous: [`{id: a}`, `{id: b}`, `{id: c}`]
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: [`{id: a}`, `{id: b}`, `{id: c}`],
identityChanges: [`{id: a}`, `{id: b}`, `{id: c}`],
previous: [`{id: a}`, `{id: b}`, `{id: c}`]
}));
});
it('should have updated properties in identity change collection', () => {
@@ -383,11 +407,12 @@ export function main() {
l = [new ComplexItem('a', 'orange'), new ComplexItem('b', 'red')];
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: [`{id: a, color: orange}`, `{id: b, color: red}`],
identityChanges: [`{id: a, color: orange}`, `{id: b, color: red}`],
previous: [`{id: a, color: orange}`, `{id: b, color: red}`]
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: [`{id: a, color: orange}`, `{id: b, color: red}`],
identityChanges: [`{id: a, color: orange}`, `{id: b, color: red}`],
previous: [`{id: a, color: orange}`, `{id: b, color: red}`]
}));
});
it('should track moves normally', () => {
@@ -396,12 +421,13 @@ export function main() {
l = buildItemList(['b', 'a', 'c']);
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['{id: b}[1->0]', '{id: a}[0->1]', '{id: c}'],
identityChanges: ['{id: b}[1->0]', '{id: a}[0->1]', '{id: c}'],
previous: ['{id: a}[0->1]', '{id: b}[1->0]', '{id: c}'],
moves: ['{id: b}[1->0]', '{id: a}[0->1]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['{id: b}[1->0]', '{id: a}[0->1]', '{id: c}'],
identityChanges: ['{id: b}[1->0]', '{id: a}[0->1]', '{id: c}'],
previous: ['{id: a}[0->1]', '{id: b}[1->0]', '{id: c}'],
moves: ['{id: b}[1->0]', '{id: a}[0->1]']
}));
});
@@ -411,13 +437,14 @@ export function main() {
l = buildItemList(['b', 'a', 'a']);
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['{id: b}[null->0]', '{id: a}[0->1]', '{id: a}[1->2]'],
identityChanges: ['{id: a}[0->1]', '{id: a}[1->2]'],
previous: ['{id: a}[0->1]', '{id: a}[1->2]'],
moves: ['{id: a}[0->1]', '{id: a}[1->2]'],
additions: ['{id: b}[null->0]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['{id: b}[null->0]', '{id: a}[0->1]', '{id: a}[1->2]'],
identityChanges: ['{id: a}[0->1]', '{id: a}[1->2]'],
previous: ['{id: a}[0->1]', '{id: a}[1->2]'],
moves: ['{id: a}[0->1]', '{id: a}[1->2]'],
additions: ['{id: b}[null->0]']
}));
});
@@ -427,11 +454,12 @@ export function main() {
ListWrapper.removeAt(l, 2);
differ.check(l);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['{id: a}', '{id: b}'],
previous: ['{id: a}', '{id: b}', '{id: c}[2->null]'],
removals: ['{id: c}[2->null]']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['{id: a}', '{id: b}'],
previous: ['{id: a}', '{id: b}', '{id: c}[2->null]'],
removals: ['{id: c}[2->null]']
}));
});
});
describe('trackBy function by index', function() {
@@ -446,12 +474,13 @@ export function main() {
differ.check(['e', 'f', 'g', 'h']);
differ.check(['e', 'f', 'h']);
expect(differ.toString()).toEqual(iterableChangesAsString({
collection: ['e', 'f', 'h'],
previous: ['e', 'f', 'h', 'h[3->null]'],
removals: ['h[3->null]'],
identityChanges: ['h']
}));
expect(differ.toString())
.toEqual(iterableChangesAsString({
collection: ['e', 'f', 'h'],
previous: ['e', 'f', 'h', 'h[3->null]'],
removals: ['h[3->null]'],
identityChanges: ['h']
}));
});
});
@@ -1,5 +1,17 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {DefaultKeyValueDiffer, DefaultKeyValueDifferFactory} from 'angular2/src/core/change_detection/differs/default_keyvalue_differ';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {
DefaultKeyValueDiffer,
DefaultKeyValueDifferFactory
} from 'angular2/src/core/change_detection/differs/default_keyvalue_differ';
import {NumberWrapper, isJsObject} from 'angular2/src/facade/lang';
import {kvChangesAsString} from '../../../core/change_detection/util';
@@ -40,11 +52,12 @@ export function main() {
m.set(2, 10);
m.set(1, 20);
differ.check(m);
expect(differ.toString()).toEqual(kvChangesAsString({
map: ['1[10->20]', '2[20->10]'],
previous: ['1[10->20]', '2[20->10]'],
changes: ['1[10->20]', '2[20->10]']
}));
expect(differ.toString())
.toEqual(kvChangesAsString({
map: ['1[10->20]', '2[20->10]'],
previous: ['1[10->20]', '2[20->10]'],
changes: ['1[10->20]', '2[20->10]']
}));
});
it('should expose previous and current value', () => {
@@ -82,12 +95,13 @@ export function main() {
m.set('b', 'BB');
m.set('d', 'D');
differ.check(m);
expect(differ.toString()).toEqual(kvChangesAsString({
map: ['a', 'b[B->BB]', 'd[null->D]'],
previous: ['a', 'b[B->BB]'],
additions: ['d[null->D]'],
changes: ['b[B->BB]']
}));
expect(differ.toString())
.toEqual(kvChangesAsString({
map: ['a', 'b[B->BB]', 'd[null->D]'],
previous: ['a', 'b[B->BB]'],
additions: ['d[null->D]'],
changes: ['b[B->BB]']
}));
m.delete('b');
differ.check(m);
@@ -97,10 +111,9 @@ export function main() {
m.clear();
differ.check(m);
expect(differ.toString()).toEqual(kvChangesAsString({
previous: ['a[A->null]', 'd[D->null]'],
removals: ['a[A->null]', 'd[D->null]']
}));
expect(differ.toString())
.toEqual(kvChangesAsString(
{previous: ['a[A->null]', 'd[D->null]'], removals: ['a[A->null]', 'd[D->null]']}));
});
it('should test string by value rather than by reference (DART)', () => {
@@ -132,7 +145,7 @@ export function main() {
it('should support JS Object', () => {
var f = new DefaultKeyValueDifferFactory();
expect(f.supports({})).toBeTruthy();
expect(f.supports('not supported')).toBeFalsy();
expect(f.supports("not supported")).toBeFalsy();
expect(f.supports(0)).toBeFalsy();
expect(f.supports(null)).toBeFalsy();
});
@@ -155,29 +168,32 @@ export function main() {
m['b'] = 'BB';
m['d'] = 'D';
differ.check(m);
expect(differ.toString()).toEqual(kvChangesAsString({
map: ['a', 'b[B->BB]', 'd[null->D]'],
previous: ['a', 'b[B->BB]'],
additions: ['d[null->D]'],
changes: ['b[B->BB]']
}));
expect(differ.toString())
.toEqual(kvChangesAsString({
map: ['a', 'b[B->BB]', 'd[null->D]'],
previous: ['a', 'b[B->BB]'],
additions: ['d[null->D]'],
changes: ['b[B->BB]']
}));
m = {};
m['a'] = 'A';
m['d'] = 'D';
differ.check(m);
expect(differ.toString()).toEqual(kvChangesAsString({
map: ['a', 'd'],
previous: ['a', 'b[BB->null]', 'd'],
removals: ['b[BB->null]']
}));
expect(differ.toString())
.toEqual(kvChangesAsString({
map: ['a', 'd'],
previous: ['a', 'b[BB->null]', 'd'],
removals: ['b[BB->null]']
}));
m = {};
differ.check(m);
expect(differ.toString()).toEqual(kvChangesAsString({
previous: ['a[A->null]', 'd[D->null]'],
removals: ['a[A->null]', 'd[D->null]']
}));
expect(differ.toString())
.toEqual(kvChangesAsString({
previous: ['a[A->null]', 'd[D->null]'],
removals: ['a[A->null]', 'd[D->null]']
}));
});
});
@@ -201,8 +217,7 @@ export function main() {
});
it('should throw when given an invalid collection', () => {
expect(() => differ.diff('invalid'))
.toThrowErrorWith('Error trying to diff \'invalid\'');
expect(() => differ.diff("invalid")).toThrowErrorWith("Error trying to diff 'invalid'");
});
});
}
@@ -1,4 +1,13 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {SpyIterableDifferFactory} from '../../spies';
import {IterableDiffers} from 'angular2/src/core/change_detection/differs/iterable_differs';
import {Injector, provide} from 'angular2/core';
@@ -17,22 +26,22 @@ export function main() {
it('should throw when no suitable implementation found', () => {
var differs = new IterableDiffers([]);
expect(() => differs.find('some object'))
.toThrowErrorWith('Cannot find a differ supporting object \'some object\'')
expect(() => differs.find("some object"))
.toThrowErrorWith("Cannot find a differ supporting object 'some object'")
});
it('should return the first suitable implementation', () => {
factory1.spy('supports').andReturn(false);
factory2.spy('supports').andReturn(true);
factory3.spy('supports').andReturn(true);
factory1.spy("supports").andReturn(false);
factory2.spy("supports").andReturn(true);
factory3.spy("supports").andReturn(true);
var differs = IterableDiffers.create(<any>[factory1, factory2, factory3]);
expect(differs.find('some object')).toBe(factory2);
expect(differs.find("some object")).toBe(factory2);
});
it('should copy over differs from the parent repo', () => {
factory1.spy('supports').andReturn(true);
factory2.spy('supports').andReturn(false);
factory1.spy("supports").andReturn(true);
factory2.spy("supports").andReturn(false);
var parent = IterableDiffers.create(<any>[factory1]);
var child = IterableDiffers.create(<any>[factory2], parent);
@@ -40,12 +49,12 @@ export function main() {
expect(child.factories).toEqual([factory2, factory1]);
});
describe('.extend()', () => {
describe(".extend()", () => {
it('should throw if calling extend when creating root injector', () => {
var injector = Injector.resolveAndCreate([IterableDiffers.extend([])]);
expect(() => injector.get(IterableDiffers))
.toThrowErrorWith('Cannot extend IterableDiffers without a parent injector');
.toThrowErrorWith("Cannot extend IterableDiffers without a parent injector");
});
it('should extend di-inherited diffesr', () => {
@@ -2,7 +2,7 @@ import {ddescribe, describe, it, expect} from 'angular2/testing_internal';
import {Lexer, Token} from 'angular2/src/core/change_detection/parser/lexer';
import {StringWrapper} from 'angular2/src/facade/lang';
import {StringWrapper} from "angular2/src/facade/lang";
function lex(text: string): any[] {
return new Lexer().tokenize(text);
@@ -52,13 +52,13 @@ export function main() {
describe('lexer', function() {
describe('token', function() {
it('should tokenize a simple identifier', function() {
var tokens: number[] = lex('j');
var tokens: number[] = lex("j");
expect(tokens.length).toEqual(1);
expectIdentifierToken(tokens[0], 0, 'j');
});
it('should tokenize a dotted identifier', function() {
var tokens: number[] = lex('j.k');
var tokens: number[] = lex("j.k");
expect(tokens.length).toEqual(3);
expectIdentifierToken(tokens[0], 0, 'j');
expectCharacterToken(tokens[1], 1, '.');
@@ -66,35 +66,35 @@ export function main() {
});
it('should tokenize an operator', function() {
var tokens: number[] = lex('j-k');
var tokens: number[] = lex("j-k");
expect(tokens.length).toEqual(3);
expectOperatorToken(tokens[1], 1, '-');
});
it('should tokenize an indexed operator', function() {
var tokens: number[] = lex('j[k]');
var tokens: number[] = lex("j[k]");
expect(tokens.length).toEqual(4);
expectCharacterToken(tokens[1], 1, '[');
expectCharacterToken(tokens[3], 3, ']');
expectCharacterToken(tokens[1], 1, "[");
expectCharacterToken(tokens[3], 3, "]");
});
it('should tokenize numbers', function() {
var tokens: number[] = lex('88');
var tokens: number[] = lex("88");
expect(tokens.length).toEqual(1);
expectNumberToken(tokens[0], 0, 88);
});
it('should tokenize numbers within index ops',
function() { expectNumberToken(lex('a[22]')[2], 2, 22); });
function() { expectNumberToken(lex("a[22]")[2], 2, 22); });
it('should tokenize simple quoted strings',
function() { expectStringToken(lex('"a"')[0], 0, 'a'); });
function() { expectStringToken(lex('"a"')[0], 0, "a"); });
it('should tokenize quoted strings with escaped quotes',
function() { expectStringToken(lex('"a\\""')[0], 0, 'a"'); });
it('should tokenize a string', function() {
var tokens: Token[] = lex('j-a.bc[22]+1.3|f:\'a\\\'c\':"d\\"e"');
var tokens: Token[] = lex("j-a.bc[22]+1.3|f:'a\\\'c':\"d\\\"e\"");
expectIdentifierToken(tokens[0], 0, 'j');
expectOperatorToken(tokens[1], 1, '-');
expectIdentifierToken(tokens[2], 2, 'a');
@@ -108,27 +108,27 @@ export function main() {
expectOperatorToken(tokens[10], 14, '|');
expectIdentifierToken(tokens[11], 15, 'f');
expectCharacterToken(tokens[12], 16, ':');
expectStringToken(tokens[13], 17, 'a\'c');
expectStringToken(tokens[13], 17, "a'c");
expectCharacterToken(tokens[14], 23, ':');
expectStringToken(tokens[15], 24, 'd"e');
});
it('should tokenize undefined', function() {
var tokens: Token[] = lex('undefined');
expectKeywordToken(tokens[0], 0, 'undefined');
var tokens: Token[] = lex("undefined");
expectKeywordToken(tokens[0], 0, "undefined");
expect(tokens[0].isKeywordUndefined()).toBe(true);
});
it('should ignore whitespace', function() {
var tokens: Token[] = lex('a \t \n \r b');
var tokens: Token[] = lex("a \t \n \r b");
expectIdentifierToken(tokens[0], 0, 'a');
expectIdentifierToken(tokens[1], 8, 'b');
});
it('should tokenize quoted string', () => {
var str = '[\'\\\'\', "\\""]';
var str = "['\\'', \"\\\"\"]";
var tokens: Token[] = lex(str);
expectStringToken(tokens[1], 1, '\'');
expectStringToken(tokens[1], 1, "'");
expectStringToken(tokens[3], 7, '"');
});
@@ -146,7 +146,7 @@ export function main() {
});
it('should tokenize relation', function() {
var tokens: Token[] = lex('! == != < > <= >= === !==');
var tokens: Token[] = lex("! == != < > <= >= === !==");
expectOperatorToken(tokens[0], 0, '!');
expectOperatorToken(tokens[1], 2, '==');
expectOperatorToken(tokens[2], 5, '!=');
@@ -159,7 +159,7 @@ export function main() {
});
it('should tokenize statements', function() {
var tokens: Token[] = lex('a;b;');
var tokens: Token[] = lex("a;b;");
expectIdentifierToken(tokens[0], 0, 'a');
expectCharacterToken(tokens[1], 1, ';');
expectIdentifierToken(tokens[2], 2, 'b');
@@ -167,19 +167,19 @@ export function main() {
});
it('should tokenize function invocation', function() {
var tokens: Token[] = lex('a()');
var tokens: Token[] = lex("a()");
expectIdentifierToken(tokens[0], 0, 'a');
expectCharacterToken(tokens[1], 1, '(');
expectCharacterToken(tokens[2], 2, ')');
});
it('should tokenize simple method invocations', function() {
var tokens: Token[] = lex('a.method()');
var tokens: Token[] = lex("a.method()");
expectIdentifierToken(tokens[2], 2, 'method');
});
it('should tokenize method invocation', function() {
var tokens: Token[] = lex('a.b.c (d) - e.f()');
var tokens: Token[] = lex("a.b.c (d) - e.f()");
expectIdentifierToken(tokens[0], 0, 'a');
expectCharacterToken(tokens[1], 1, '.');
expectIdentifierToken(tokens[2], 2, 'b');
@@ -197,7 +197,7 @@ export function main() {
});
it('should tokenize number', function() {
var tokens: Token[] = lex('0.5');
var tokens: Token[] = lex("0.5");
expectNumberToken(tokens[0], 0, 0.5);
});
@@ -208,36 +208,34 @@ export function main() {
// });
it('should tokenize number with exponent', function() {
var tokens: Token[] = lex('0.5E-10');
var tokens: Token[] = lex("0.5E-10");
expect(tokens.length).toEqual(1);
expectNumberToken(tokens[0], 0, 0.5E-10);
tokens = lex('0.5E+10');
tokens = lex("0.5E+10");
expectNumberToken(tokens[0], 0, 0.5E+10);
});
it('should throws exception for invalid exponent', function() {
expect(() => {
lex('0.5E-');
}).toThrowError('Lexer Error: Invalid exponent at column 4 in expression [0.5E-]');
expect(() => { lex("0.5E-"); })
.toThrowError('Lexer Error: Invalid exponent at column 4 in expression [0.5E-]');
expect(() => {
lex('0.5E-A');
}).toThrowError('Lexer Error: Invalid exponent at column 4 in expression [0.5E-A]');
expect(() => { lex("0.5E-A"); })
.toThrowError('Lexer Error: Invalid exponent at column 4 in expression [0.5E-A]');
});
it('should tokenize number starting with a dot', function() {
var tokens: Token[] = lex('.5');
var tokens: Token[] = lex(".5");
expectNumberToken(tokens[0], 0, 0.5);
});
it('should throw error on invalid unicode', function() {
expect(() => { lex('\'\\u1\'\'bla\''); })
expect(() => { lex("'\\u1''bla'"); })
.toThrowError(
'Lexer Error: Invalid unicode escape [\\u1\'\'b] at column 2 in expression [\'\\u1\'\'bla\']');
"Lexer Error: Invalid unicode escape [\\u1''b] at column 2 in expression ['\\u1''bla']");
});
it('should tokenize hash as operator', function() {
var tokens: Token[] = lex('#');
var tokens: Token[] = lex("#");
expectOperatorToken(tokens[0], 0, '#');
});
@@ -13,7 +13,7 @@ export function main() {
it('should support getting values', () => {
expect(locals.get('key')).toBe('value');
expect(() => locals.get('notPresent')).toThrowError(new RegExp('Cannot find'));
expect(() => locals.get('notPresent')).toThrowError(new RegExp("Cannot find"));
});
it('should support checking if key is present', () => {
@@ -53,86 +53,86 @@ export function main() {
function expectBindingError(text) { return expect(() => parseBinding(text)); }
describe('parser', () => {
describe('parseAction', () => {
it('should parse numbers', () => { checkAction('1'); });
describe("parser", () => {
describe("parseAction", () => {
it('should parse numbers', () => { checkAction("1"); });
it('should parse strings', () => {
checkAction('\'1\'', '"1"');
checkAction("'1'", '"1"');
checkAction('"1"');
});
it('should parse null', () => { checkAction('null'); });
it('should parse null', () => { checkAction("null"); });
it('should parse unary - expressions', () => {
checkAction('-1', '0 - 1');
checkAction('+1', '1');
checkAction("-1", "0 - 1");
checkAction("+1", "1");
});
it('should parse unary ! expressions', () => {
checkAction('!true');
checkAction('!!true');
checkAction('!!!true');
checkAction("!true");
checkAction("!!true");
checkAction("!!!true");
});
it('should parse multiplicative expressions',
() => { checkAction('3*4/2%5', '3 * 4 / 2 % 5'); });
() => { checkAction("3*4/2%5", "3 * 4 / 2 % 5"); });
it('should parse additive expressions', () => { checkAction('3 + 6 - 2'); });
it('should parse additive expressions', () => { checkAction("3 + 6 - 2"); });
it('should parse relational expressions', () => {
checkAction('2 < 3');
checkAction('2 > 3');
checkAction('2 <= 2');
checkAction('2 >= 2');
checkAction("2 < 3");
checkAction("2 > 3");
checkAction("2 <= 2");
checkAction("2 >= 2");
});
it('should parse equality expressions', () => {
checkAction('2 == 3');
checkAction('2 != 3');
checkAction("2 == 3");
checkAction("2 != 3");
});
it('should parse strict equality expressions', () => {
checkAction('2 === 3');
checkAction('2 !== 3');
checkAction("2 === 3");
checkAction("2 !== 3");
});
it('should parse expressions', () => {
checkAction('true && true');
checkAction('true || false');
checkAction("true && true");
checkAction("true || false");
});
it('should parse grouped expressions', () => { checkAction('(1 + 2) * 3', '1 + 2 * 3'); });
it('should parse grouped expressions', () => { checkAction("(1 + 2) * 3", "1 + 2 * 3"); });
it('should parse an empty string', () => { checkAction(''); });
describe('literals', () => {
describe("literals", () => {
it('should parse array', () => {
checkAction('[1][0]');
checkAction('[[1]][0][0]');
checkAction('[]');
checkAction('[].length');
checkAction('[1, 2].length');
checkAction("[1][0]");
checkAction("[[1]][0][0]");
checkAction("[]");
checkAction("[].length");
checkAction("[1, 2].length");
});
it('should parse map', () => {
checkAction('{}');
checkAction('{a: 1}[2]');
checkAction('{}["a"]');
checkAction("{}");
checkAction("{a: 1}[2]");
checkAction("{}[\"a\"]");
});
it('should only allow identifier, string, or keyword as map key', () => {
expectActionError('{(:0}').toThrowError(
new RegExp('expected identifier, keyword, or string'));
expectActionError('{(:0}')
.toThrowError(new RegExp('expected identifier, keyword, or string'));
expectActionError('{1234:0}')
.toThrowError(new RegExp('expected identifier, keyword, or string'));
});
});
describe('member access', () => {
it('should parse field access', () => {
checkAction('a');
checkAction('a.a');
describe("member access", () => {
it("should parse field access", () => {
checkAction("a");
checkAction("a.a");
});
it('should only allow identifier or keyword as member names', () => {
@@ -147,47 +147,46 @@ export function main() {
});
});
describe('method calls', () => {
it('should parse method calls', () => {
checkAction('fn()');
checkAction('add(1, 2)');
checkAction('a.add(1, 2)');
checkAction('fn().add(1, 2)');
describe("method calls", () => {
it("should parse method calls", () => {
checkAction("fn()");
checkAction("add(1, 2)");
checkAction("a.add(1, 2)");
checkAction("fn().add(1, 2)");
});
});
describe('functional calls', () => {
it('should parse function calls', () => { checkAction('fn()(1, 2)'); });
});
describe("functional calls",
() => { it("should parse function calls", () => { checkAction("fn()(1, 2)"); }); });
describe('conditional', () => {
describe("conditional", () => {
it('should parse ternary/conditional expressions', () => {
checkAction('7 == 3 + 4 ? 10 : 20');
checkAction('false ? 10 : 20');
checkAction("7 == 3 + 4 ? 10 : 20");
checkAction("false ? 10 : 20");
});
it('should throw on incorrect ternary operator syntax', () => {
expectActionError('true?1').toThrowError(new RegExp(
expectActionError("true?1").toThrowError(new RegExp(
'Parser Error: Conditional expression true\\?1 requires all 3 expressions'));
});
});
describe('assignment', () => {
it('should support field assignments', () => {
checkAction('a = 12');
checkAction('a.a.a = 123');
checkAction('a = 123; b = 234;');
describe("assignment", () => {
it("should support field assignments", () => {
checkAction("a = 12");
checkAction("a.a.a = 123");
checkAction("a = 123; b = 234;");
});
it('should throw on safe field assignments', () => {
expectActionError('a?.a = 123')
it("should throw on safe field assignments", () => {
expectActionError("a?.a = 123")
.toThrowError(new RegExp('cannot be used in the assignment'));
});
it('should support array updates', () => { checkAction('a[0] = 200'); });
it("should support array updates", () => { checkAction("a[0] = 200"); });
});
it('should error when using pipes',
it("should error when using pipes",
() => { expectActionError('x|blah').toThrowError(new RegExp('Cannot have a pipe')); });
it('should store the source in the result',
@@ -196,31 +195,31 @@ export function main() {
it('should store the passed-in location',
() => { expect(parseAction('someExpr', 'location').location).toBe('location'); });
it('should throw when encountering interpolation', () => {
expectActionError('{{a()}}').toThrowErrorWith(
'Got interpolation ({{}}) where expression was expected');
it("should throw when encountering interpolation", () => {
expectActionError("{{a()}}")
.toThrowErrorWith('Got interpolation ({{}}) where expression was expected');
});
});
describe('general error handling', () => {
it('should throw on an unexpected token', () => {
expectActionError('[1,2] trac').toThrowError(new RegExp('Unexpected token \'trac\''));
describe("general error handling", () => {
it("should throw on an unexpected token", () => {
expectActionError("[1,2] trac").toThrowError(new RegExp('Unexpected token \'trac\''));
});
it('should throw a reasonable error for unconsumed tokens', () => {
expectActionError(')').toThrowError(
new RegExp('Unexpected token \\) at column 1 in \\[\\)\\]'));
expectActionError(")")
.toThrowError(new RegExp("Unexpected token \\) at column 1 in \\[\\)\\]"));
});
it('should throw on missing expected token', () => {
expectActionError('a(b').toThrowError(
new RegExp('Missing expected \\) at the end of the expression \\[a\\(b\\]'));
expectActionError("a(b").toThrowError(
new RegExp("Missing expected \\) at the end of the expression \\[a\\(b\\]"));
});
});
describe('parseBinding', () => {
describe('pipes', () => {
it('should parse pipes', () => {
describe("parseBinding", () => {
describe("pipes", () => {
it("should parse pipes", () => {
checkBinding('a(b | c)', 'a((b | c))');
checkBinding('a.b(c.d(e) | f)', 'a.b((c.d(e) | f))');
checkBinding('[1, 2, 3] | a', '([1, 2, 3] | a)');
@@ -258,16 +257,16 @@ export function main() {
() => { expect(parseBinding('someExpr', 'location').location).toBe('location'); });
it('should throw on chain expressions', () => {
expect(() => parseBinding('1;2')).toThrowError(new RegExp('contain chained expression'));
expect(() => parseBinding("1;2")).toThrowError(new RegExp("contain chained expression"));
});
it('should throw on assignment', () => {
expect(() => parseBinding('a=2')).toThrowError(new RegExp('contain assignments'));
expect(() => parseBinding("a=2")).toThrowError(new RegExp("contain assignments"));
});
it('should throw when encountering interpolation', () => {
expectBindingError('{{a.b}}').toThrowErrorWith(
'Got interpolation ({{}}) where expression was expected');
expectBindingError("{{a.b}}")
.toThrowErrorWith('Got interpolation ({{}}) where expression was expected');
});
it('should parse conditional expression', () => { checkBinding('a < b ? a : b'); });
@@ -300,93 +299,90 @@ export function main() {
() => { expect(keys(parseTemplateBindings('a'))).toEqual(['a']); });
it('should only allow identifier, string, or keyword including dashes as keys', () => {
var bindings = parseTemplateBindings('a:\'b\'');
var bindings = parseTemplateBindings("a:'b'");
expect(keys(bindings)).toEqual(['a']);
bindings = parseTemplateBindings('\'a\':\'b\'');
bindings = parseTemplateBindings("'a':'b'");
expect(keys(bindings)).toEqual(['a']);
bindings = parseTemplateBindings('"a":\'b\'');
bindings = parseTemplateBindings("\"a\":'b'");
expect(keys(bindings)).toEqual(['a']);
bindings = parseTemplateBindings('a-b:\'c\'');
bindings = parseTemplateBindings("a-b:'c'");
expect(keys(bindings)).toEqual(['a-b']);
expect(() => {
parseTemplateBindings('(:0');
}).toThrowError(new RegExp('expected identifier, keyword, or string'));
expect(() => { parseTemplateBindings('(:0'); })
.toThrowError(new RegExp('expected identifier, keyword, or string'));
expect(() => {
parseTemplateBindings('1234:0');
}).toThrowError(new RegExp('expected identifier, keyword, or string'));
expect(() => { parseTemplateBindings('1234:0'); })
.toThrowError(new RegExp('expected identifier, keyword, or string'));
});
it('should detect expressions as value', () => {
var bindings = parseTemplateBindings('a:b');
var bindings = parseTemplateBindings("a:b");
expect(exprSources(bindings)).toEqual(['b']);
bindings = parseTemplateBindings('a:1+1');
bindings = parseTemplateBindings("a:1+1");
expect(exprSources(bindings)).toEqual(['1+1']);
});
it('should detect names as value', () => {
var bindings = parseTemplateBindings('a:#b');
var bindings = parseTemplateBindings("a:#b");
expect(keyValues(bindings)).toEqual(['a', '#b=\$implicit']);
});
it('should allow space and colon as separators', () => {
var bindings = parseTemplateBindings('a:b');
var bindings = parseTemplateBindings("a:b");
expect(keys(bindings)).toEqual(['a']);
expect(exprSources(bindings)).toEqual(['b']);
bindings = parseTemplateBindings('a b');
bindings = parseTemplateBindings("a b");
expect(keys(bindings)).toEqual(['a']);
expect(exprSources(bindings)).toEqual(['b']);
});
it('should allow multiple pairs', () => {
var bindings = parseTemplateBindings('a 1 b 2');
var bindings = parseTemplateBindings("a 1 b 2");
expect(keys(bindings)).toEqual(['a', 'aB']);
expect(exprSources(bindings)).toEqual(['1 ', '2']);
});
it('should store the sources in the result', () => {
var bindings = parseTemplateBindings('a 1,b 2');
var bindings = parseTemplateBindings("a 1,b 2");
expect(bindings[0].expression.source).toEqual('1');
expect(bindings[1].expression.source).toEqual('2');
});
it('should store the passed-in location', () => {
var bindings = parseTemplateBindings('a 1,b 2', 'location');
var bindings = parseTemplateBindings("a 1,b 2", 'location');
expect(bindings[0].expression.location).toEqual('location');
});
it('should support var/# notation', () => {
var bindings = parseTemplateBindings('var i');
var bindings = parseTemplateBindings("var i");
expect(keyValues(bindings)).toEqual(['#i=\$implicit']);
bindings = parseTemplateBindings('#i');
bindings = parseTemplateBindings("#i");
expect(keyValues(bindings)).toEqual(['#i=\$implicit']);
bindings = parseTemplateBindings('var a; var b');
bindings = parseTemplateBindings("var a; var b");
expect(keyValues(bindings)).toEqual(['#a=\$implicit', '#b=\$implicit']);
bindings = parseTemplateBindings('#a; #b;');
bindings = parseTemplateBindings("#a; #b;");
expect(keyValues(bindings)).toEqual(['#a=\$implicit', '#b=\$implicit']);
bindings = parseTemplateBindings('var i-a = k-a');
bindings = parseTemplateBindings("var i-a = k-a");
expect(keyValues(bindings)).toEqual(['#i-a=k-a']);
bindings = parseTemplateBindings('keyword var item; var i = k');
bindings = parseTemplateBindings("keyword var item; var i = k");
expect(keyValues(bindings)).toEqual(['keyword', '#item=\$implicit', '#i=k']);
bindings = parseTemplateBindings('keyword: #item; #i = k');
bindings = parseTemplateBindings("keyword: #item; #i = k");
expect(keyValues(bindings)).toEqual(['keyword', '#item=\$implicit', '#i=k']);
bindings = parseTemplateBindings('directive: var item in expr; var a = b', 'location');
expect(keyValues(bindings)).toEqual([
'directive', '#item=\$implicit', 'directiveIn=expr in location', '#a=b'
]);
bindings = parseTemplateBindings("directive: var item in expr; var a = b", 'location');
expect(keyValues(bindings))
.toEqual(['directive', '#item=\$implicit', 'directiveIn=expr in location', '#a=b']);
});
it('should parse pipes', () => {
@@ -413,14 +409,14 @@ export function main() {
expect(new Unparser().unparse(ast)).toEqual(originalExp);
});
it('should throw on empty interpolation expressions', () => {
expect(() => parseInterpolation('{{}}'))
it("should throw on empty interpolation expressions", () => {
expect(() => parseInterpolation("{{}}"))
.toThrowErrorWith(
'Parser Error: Blank expressions are not allowed in interpolated strings');
"Parser Error: Blank expressions are not allowed in interpolated strings");
expect(() => parseInterpolation('foo {{ }}'))
expect(() => parseInterpolation("foo {{ }}"))
.toThrowErrorWith(
'Parser Error: Blank expressions are not allowed in interpolated strings');
"Parser Error: Blank expressions are not allowed in interpolated strings");
});
it('should parse conditional expression',
@@ -431,19 +427,19 @@ export function main() {
});
});
describe('parseSimpleBinding', () => {
it('should parse a field access', () => {
var p = parseSimpleBinding('name');
expect(unparse(p)).toEqual('name');
describe("parseSimpleBinding", () => {
it("should parse a field access", () => {
var p = parseSimpleBinding("name");
expect(unparse(p)).toEqual("name");
});
it('should parse a constant', () => {
var p = parseSimpleBinding('[1, 2]');
expect(unparse(p)).toEqual('[1, 2]');
it("should parse a constant", () => {
var p = parseSimpleBinding("[1, 2]");
expect(unparse(p)).toEqual("[1, 2]");
});
it('should throw when the given expression is not just a field name', () => {
expect(() => parseSimpleBinding('name + 1'))
it("should throw when the given expression is not just a field name", () => {
expect(() => parseSimpleBinding("name + 1"))
.toThrowErrorWith(
'Host binding expression can only contain field access and constants');
});
@@ -456,7 +452,7 @@ export function main() {
describe('wrapLiteralPrimitive', () => {
it('should wrap a literal primitive', () => {
expect(unparse(createParser().wrapLiteralPrimitive('foo', null))).toEqual('"foo"');
expect(unparse(createParser().wrapLiteralPrimitive("foo", null))).toEqual('"foo"');
});
});
});
@@ -1,4 +1,27 @@
import {AST, AstVisitor, PropertyRead, PropertyWrite, Binary, Chain, Conditional, EmptyExpr, BindingPipe, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, PrefixNot, Quote, SafePropertyRead, SafeMethodCall} from 'angular2/src/core/change_detection/parser/ast';
import {
AST,
AstVisitor,
PropertyRead,
PropertyWrite,
Binary,
Chain,
Conditional,
EmptyExpr,
BindingPipe,
FunctionCall,
ImplicitReceiver,
Interpolation,
KeyedRead,
KeyedWrite,
LiteralArray,
LiteralMap,
LiteralPrimitive,
MethodCall,
PrefixNot,
Quote,
SafePropertyRead,
SafeMethodCall
} from 'angular2/src/core/change_detection/parser/ast';
import {StringWrapper, isPresent, isString} from 'angular2/src/facade/lang';
@@ -1,15 +1,25 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, inject} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
inject
} from 'angular2/testing_internal';
import {ProtoRecordBuilder} from 'angular2/src/core/change_detection/proto_change_detector';
import {BindingRecord} from 'angular2/src/core/change_detection/binding_record';
import {Parser} from 'angular2/src/core/change_detection/parser/parser';
export function main() {
describe('ProtoRecordBuilder', () => {
describe("ProtoRecordBuilder", () => {
it('should set argumentToPureFunction flag', inject([Parser], (p: Parser) => {
var builder = new ProtoRecordBuilder();
var ast = p.parseBinding('[1,2]', 'location'); // collection literal is a pure function
builder.add(BindingRecord.createForElementProperty(ast, 0, 'property'), [], 0);
var ast = p.parseBinding("[1,2]", "location"); // collection literal is a pure function
builder.add(BindingRecord.createForElementProperty(ast, 0, "property"), [], 0);
var isPureFunc = builder.records.map(r => r.argumentToPureFunction);
expect(isPureFunc).toEqual([true, true, false]);
@@ -18,8 +28,8 @@ export function main() {
it('should not set argumentToPureFunction flag when not needed',
inject([Parser], (p: Parser) => {
var builder = new ProtoRecordBuilder();
var ast = p.parseBinding('f(1,2)', 'location');
builder.add(BindingRecord.createForElementProperty(ast, 0, 'property'), [], 0);
var ast = p.parseBinding("f(1,2)", "location");
builder.add(BindingRecord.createForElementProperty(ast, 0, "property"), [], 0);
var isPureFunc = builder.records.map(r => r.argumentToPureFunction);
expect(isPureFunc).toEqual([false, false, false]);
@@ -1,4 +1,13 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/testing_internal';
import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach
} from 'angular2/testing_internal';
import {isBlank} from 'angular2/src/facade/lang';
import {RecordType, ProtoRecord} from 'angular2/src/core/change_detection/proto_record';
@@ -15,17 +24,16 @@ export function main() {
} = {}) {
if (isBlank(lastInBinding)) lastInBinding = false;
if (isBlank(mode)) mode = RecordType.PropertyRead;
if (isBlank(name)) name = 'name';
if (isBlank(name)) name = "name";
if (isBlank(directiveIndex)) directiveIndex = null;
if (isBlank(argumentToPureFunction)) argumentToPureFunction = false;
if (isBlank(referencedBySelf)) referencedBySelf = false;
return new ProtoRecord(
mode, name, null, [], null, 0, directiveIndex, 0, null, lastInBinding, false,
argumentToPureFunction, referencedBySelf, 0);
return new ProtoRecord(mode, name, null, [], null, 0, directiveIndex, 0, null, lastInBinding,
false, argumentToPureFunction, referencedBySelf, 0);
}
describe('ProtoRecord', () => {
describe("ProtoRecord", () => {
describe('shouldBeChecked', () => {
it('should be true for pure functions',
() => { expect(r({mode: RecordType.CollectionLiteral}).shouldBeChecked()).toBeTruthy(); });
@@ -3,12 +3,10 @@ import {isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
export function iterableChangesAsString(
{collection = CONST_EXPR([]), previous = CONST_EXPR([]), additions = CONST_EXPR([]),
moves = CONST_EXPR([]), removals = CONST_EXPR([]), identityChanges = CONST_EXPR([])}) {
return 'collection: ' + collection.join(', ') + '\n' +
'previous: ' + previous.join(', ') + '\n' +
'additions: ' + additions.join(', ') + '\n' +
'moves: ' + moves.join(', ') + '\n' +
'removals: ' + removals.join(', ') + '\n' +
'identityChanges: ' + identityChanges.join(', ') + '\n';
return "collection: " + collection.join(', ') + "\n" + "previous: " + previous.join(', ') + "\n" +
"additions: " + additions.join(', ') + "\n" + "moves: " + moves.join(', ') + "\n" +
"removals: " + removals.join(', ') + "\n" + "identityChanges: " +
identityChanges.join(', ') + "\n";
}
export function kvChangesAsString(
@@ -21,9 +19,7 @@ export function kvChangesAsString(
if (isBlank(changes)) changes = [];
if (isBlank(removals)) removals = [];
return 'map: ' + map.join(', ') + '\n' +
'previous: ' + previous.join(', ') + '\n' +
'additions: ' + additions.join(', ') + '\n' +
'changes: ' + changes.join(', ') + '\n' +
'removals: ' + removals.join(', ') + '\n';
return "map: " + map.join(', ') + "\n" + "previous: " + previous.join(', ') + "\n" +
"additions: " + additions.join(', ') + "\n" + "changes: " + changes.join(', ') + "\n" +
"removals: " + removals.join(', ') + "\n";
}
@@ -1,4 +1,18 @@
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, dispatchEvent, expect, iit, inject, beforeEachProviders, it, xit, TestComponentBuilder} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
xdescribe,
describe,
dispatchEvent,
expect,
iit,
inject,
beforeEachProviders,
it,
xit,
TestComponentBuilder
} from 'angular2/testing_internal';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
@@ -173,70 +187,74 @@ export function main() {
describe('debug element', function() {
it('should list all child nodes',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(ParentComp).then((fixture) => {
fixture.detectChanges();
tcb.createAsync(ParentComp)
.then((fixture) => {
fixture.detectChanges();
// The root component has 3 elements and 2 text node children.
expect(fixture.debugElement.childNodes.length).toEqual(5);
async.done();
});
// The root component has 3 elements and 2 text node children.
expect(fixture.debugElement.childNodes.length).toEqual(5);
async.done();
});
}));
it('should list all component child elements',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(ParentComp).then((fixture) => {
fixture.detectChanges();
tcb.createAsync(ParentComp)
.then((fixture) => {
fixture.detectChanges();
var childEls = fixture.debugElement.children;
var childEls = fixture.debugElement.children;
// The root component has 3 elements in its view.
expect(childEls.length).toEqual(3);
expect(DOM.hasClass(childEls[0].nativeElement, 'parent')).toBe(true);
expect(DOM.hasClass(childEls[1].nativeElement, 'parent')).toBe(true);
expect(DOM.hasClass(childEls[2].nativeElement, 'child-comp-class')).toBe(true);
// The root component has 3 elements in its view.
expect(childEls.length).toEqual(3);
expect(DOM.hasClass(childEls[0].nativeElement, 'parent')).toBe(true);
expect(DOM.hasClass(childEls[1].nativeElement, 'parent')).toBe(true);
expect(DOM.hasClass(childEls[2].nativeElement, 'child-comp-class')).toBe(true);
var nested = childEls[0].children;
expect(nested.length).toEqual(1);
expect(DOM.hasClass(nested[0].nativeElement, 'parentnested')).toBe(true);
var nested = childEls[0].children;
expect(nested.length).toEqual(1);
expect(DOM.hasClass(nested[0].nativeElement, 'parentnested')).toBe(true);
var childComponent = childEls[2];
var childComponent = childEls[2];
var childCompChildren = childComponent.children;
expect(childCompChildren.length).toEqual(2);
expect(DOM.hasClass(childCompChildren[0].nativeElement, 'child')).toBe(true);
expect(DOM.hasClass(childCompChildren[1].nativeElement, 'child')).toBe(true);
var childCompChildren = childComponent.children;
expect(childCompChildren.length).toEqual(2);
expect(DOM.hasClass(childCompChildren[0].nativeElement, 'child')).toBe(true);
expect(DOM.hasClass(childCompChildren[1].nativeElement, 'child')).toBe(true);
var childNested = childCompChildren[0].children;
expect(childNested.length).toEqual(1);
expect(DOM.hasClass(childNested[0].nativeElement, 'childnested')).toBe(true);
var childNested = childCompChildren[0].children;
expect(childNested.length).toEqual(1);
expect(DOM.hasClass(childNested[0].nativeElement, 'childnested')).toBe(true);
async.done();
});
async.done();
});
}));
it('should list conditional component child elements',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(ConditionalParentComp).then((fixture) => {
fixture.detectChanges();
tcb.createAsync(ConditionalParentComp)
.then((fixture) => {
fixture.detectChanges();
var childEls = fixture.debugElement.children;
var childEls = fixture.debugElement.children;
// The root component has 2 elements in its view.
expect(childEls.length).toEqual(2);
expect(DOM.hasClass(childEls[0].nativeElement, 'parent')).toBe(true);
expect(DOM.hasClass(childEls[1].nativeElement, 'cond-content-comp-class')).toBe(true);
// The root component has 2 elements in its view.
expect(childEls.length).toEqual(2);
expect(DOM.hasClass(childEls[0].nativeElement, 'parent')).toBe(true);
expect(DOM.hasClass(childEls[1].nativeElement, 'cond-content-comp-class'))
.toBe(true);
var conditionalContentComp = childEls[1];
var conditionalContentComp = childEls[1];
expect(conditionalContentComp.children.length).toEqual(0);
expect(conditionalContentComp.children.length).toEqual(0);
conditionalContentComp.componentInstance.myBool = true;
fixture.detectChanges();
conditionalContentComp.componentInstance.myBool = true;
fixture.detectChanges();
expect(conditionalContentComp.children.length).toEqual(1);
async.done();
});
expect(conditionalContentComp.children.length).toEqual(1);
async.done();
});
}));
it('should list child elements within viewports',
@@ -270,103 +288,109 @@ export function main() {
it('should query child elements by css',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(ParentComp).then((fixture) => {
fixture.detectChanges();
tcb.createAsync(ParentComp)
.then((fixture) => {
fixture.detectChanges();
var childTestEls = fixture.debugElement.queryAll(By.css('child-comp'));
var childTestEls = fixture.debugElement.queryAll(By.css('child-comp'));
expect(childTestEls.length).toBe(1);
expect(DOM.hasClass(childTestEls[0].nativeElement, 'child-comp-class')).toBe(true);
expect(childTestEls.length).toBe(1);
expect(DOM.hasClass(childTestEls[0].nativeElement, 'child-comp-class')).toBe(true);
async.done();
});
async.done();
});
}));
it('should query child elements by directive',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(ParentComp).then((fixture) => {
fixture.detectChanges();
tcb.createAsync(ParentComp)
.then((fixture) => {
fixture.detectChanges();
var childTestEls = fixture.debugElement.queryAll(By.directive(MessageDir));
var childTestEls = fixture.debugElement.queryAll(By.directive(MessageDir));
expect(childTestEls.length).toBe(4);
expect(DOM.hasClass(childTestEls[0].nativeElement, 'parent')).toBe(true);
expect(DOM.hasClass(childTestEls[1].nativeElement, 'parentnested')).toBe(true);
expect(DOM.hasClass(childTestEls[2].nativeElement, 'child')).toBe(true);
expect(DOM.hasClass(childTestEls[3].nativeElement, 'childnested')).toBe(true);
expect(childTestEls.length).toBe(4);
expect(DOM.hasClass(childTestEls[0].nativeElement, 'parent')).toBe(true);
expect(DOM.hasClass(childTestEls[1].nativeElement, 'parentnested')).toBe(true);
expect(DOM.hasClass(childTestEls[2].nativeElement, 'child')).toBe(true);
expect(DOM.hasClass(childTestEls[3].nativeElement, 'childnested')).toBe(true);
async.done();
});
async.done();
});
}));
it('should list providerTokens',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(ParentComp).then((fixture) => {
fixture.detectChanges();
tcb.createAsync(ParentComp)
.then((fixture) => {
fixture.detectChanges();
expect(fixture.debugElement.providerTokens).toContain(Logger);
expect(fixture.debugElement.providerTokens).toContain(Logger);
async.done();
});
async.done();
});
}));
it('should list locals',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(LocalsComp).then((fixture) => {
fixture.detectChanges();
tcb.createAsync(LocalsComp)
.then((fixture) => {
fixture.detectChanges();
expect(fixture.debugElement.children[0].getLocal('alice')).toBeAnInstanceOf(MyDir);
expect(fixture.debugElement.children[0].getLocal('alice')).toBeAnInstanceOf(MyDir);
async.done();
});
async.done();
});
}));
it('should allow injecting from the element injector',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(ParentComp).then((fixture) => {
fixture.detectChanges();
tcb.createAsync(ParentComp)
.then((fixture) => {
fixture.detectChanges();
expect(fixture.debugElement.children[0].inject(Logger).log).toEqual([
'parent', 'nestedparent', 'child', 'nestedchild'
]);
expect(fixture.debugElement.children[0].inject(Logger).log)
.toEqual(['parent', 'nestedparent', 'child', 'nestedchild']);
async.done();
});
async.done();
});
}));
it('should list event listeners',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(EventsComp).then((fixture) => {
fixture.detectChanges();
tcb.createAsync(EventsComp)
.then((fixture) => {
fixture.detectChanges();
expect(fixture.debugElement.children[0].listeners.length).toEqual(1);
expect(fixture.debugElement.children[1].listeners.length).toEqual(1);
expect(fixture.debugElement.children[0].listeners.length).toEqual(1);
expect(fixture.debugElement.children[1].listeners.length).toEqual(1);
async.done();
});
async.done();
});
}));
it('should trigger event handlers',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(EventsComp).then((fixture) => {
fixture.detectChanges();
tcb.createAsync(EventsComp)
.then((fixture) => {
fixture.detectChanges();
expect(fixture.debugElement.componentInstance.clicked).toBe(false);
expect(fixture.debugElement.componentInstance.customed).toBe(false);
expect(fixture.debugElement.componentInstance.clicked).toBe(false);
expect(fixture.debugElement.componentInstance.customed).toBe(false);
fixture.debugElement.children[0].triggerEventHandler('click', <Event>{});
expect(fixture.debugElement.componentInstance.clicked).toBe(true);
fixture.debugElement.children[0].triggerEventHandler('click', <Event>{});
expect(fixture.debugElement.componentInstance.clicked).toBe(true);
fixture.debugElement.children[1].triggerEventHandler('myevent', <Event>{});
expect(fixture.debugElement.componentInstance.customed).toBe(true);
fixture.debugElement.children[1].triggerEventHandler('myevent', <Event>{});
expect(fixture.debugElement.componentInstance.customed).toBe(true);
async.done();
});
async.done();
});
}));
});
}
+15 -7
View File
@@ -1,4 +1,14 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, expect, iit, inject, it, xit,} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/testing_internal';
import {bind, provide} from 'angular2/core';
@@ -8,15 +18,13 @@ export function main() {
describe('type errors', () => {
it('should throw when trying to create a class provider and not passing a class', () => {
expect(() => {
bind('foo').toClass(<any>0);
}).toThrowError('Trying to create a class provider but "0" is not a class!');
expect(() => { bind('foo').toClass(<any>0); })
.toThrowError('Trying to create a class provider but "0" is not a class!');
});
it('should throw when trying to create a factory provider and not passing a function', () => {
expect(() => {
bind('foo').toFactory(<any>0);
}).toThrowError('Trying to create a factory provider but "0" is not a function!');
expect(() => { bind('foo').toFactory(<any>0); })
.toThrowError('Trying to create a factory provider but "0" is not a function!');
});
});
});
@@ -1,9 +1,19 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, expect, iit, inject, it, xit,} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/testing_internal';
import {forwardRef, resolveForwardRef} from 'angular2/src/core/di';
import {Type} from 'angular2/src/facade/lang';
export function main() {
describe('forwardRef', function() {
describe("forwardRef", function() {
it('should wrap and unwrap the reference', () => {
var ref = forwardRef(() => String);
expect(ref instanceof Type).toBe(true);
+152 -105
View File
@@ -2,18 +2,38 @@ import {isBlank, stringify} from 'angular2/src/facade/lang';
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
import {describe, ddescribe, it, iit, expect, beforeEach} from 'angular2/testing_internal';
import {SpyDependencyProvider} from '../spies';
import {Injector, provide, ResolvedProvider, Key, forwardRef, Injectable, InjectMetadata, SelfMetadata, HostMetadata, SkipSelfMetadata, Optional, Inject, Provider} from 'angular2/core';
import {
Injector,
provide,
ResolvedProvider,
Key,
forwardRef,
Injectable,
InjectMetadata,
SelfMetadata,
HostMetadata,
SkipSelfMetadata,
Optional,
Inject,
Provider
} from 'angular2/core';
import {DependencyMetadata} from 'angular2/src/core/di/metadata';
import {ResolvedProvider_} from 'angular2/src/core/di/provider';
import {InjectorInlineStrategy, InjectorDynamicStrategy, ProtoInjector, ProviderWithVisibility, Visibility} from 'angular2/src/core/di/injector';
import {
InjectorInlineStrategy,
InjectorDynamicStrategy,
ProtoInjector,
ProviderWithVisibility,
Visibility
} from 'angular2/src/core/di/injector';
class CustomDependencyMetadata extends DependencyMetadata {}
class Engine {}
class BrokenEngine {
constructor() { throw new BaseException('Broken Engine'); }
constructor() { throw new BaseException("Broken Engine"); }
}
class DashboardSoftware {}
@@ -72,28 +92,33 @@ function factoryFn(a) {}
export function main() {
var dynamicProviders = [
provide('provider0', {useValue: 1}), provide('provider1', {useValue: 1}),
provide('provider2', {useValue: 1}), provide('provider3', {useValue: 1}),
provide('provider4', {useValue: 1}), provide('provider5', {useValue: 1}),
provide('provider6', {useValue: 1}), provide('provider7', {useValue: 1}),
provide('provider8', {useValue: 1}), provide('provider9', {useValue: 1}),
provide('provider0', {useValue: 1}),
provide('provider1', {useValue: 1}),
provide('provider2', {useValue: 1}),
provide('provider3', {useValue: 1}),
provide('provider4', {useValue: 1}),
provide('provider5', {useValue: 1}),
provide('provider6', {useValue: 1}),
provide('provider7', {useValue: 1}),
provide('provider8', {useValue: 1}),
provide('provider9', {useValue: 1}),
provide('provider10', {useValue: 1})
];
[{strategy: 'inline', providers: [], strategyClass: InjectorInlineStrategy}, {
strategy: 'dynamic',
providers: dynamicProviders,
strategyClass: InjectorDynamicStrategy
}].forEach((context) => {
[{strategy: 'inline', providers: [], strategyClass: InjectorInlineStrategy},
{
strategy: 'dynamic',
providers: dynamicProviders,
strategyClass: InjectorDynamicStrategy
}].forEach((context) => {
function createInjector(providers: any[], parent: Injector = null, isHost: boolean = false) {
return new Injector(
ProtoInjector.fromResolvedProviders(
Injector.resolve(providers.concat(context['providers']))),
parent, isHost);
return new Injector(ProtoInjector.fromResolvedProviders(
Injector.resolve(providers.concat(context['providers']))),
parent, isHost);
}
describe(`injector ${context['strategy']}`, () => {
it('should use the right strategy', () => {
it("should use the right strategy", () => {
var injector = createInjector([]);
expect(injector.internalStrategy).toBeAnInstanceOf(context['strategyClass']);
});
@@ -124,17 +149,17 @@ export function main() {
it('should throw when no type and not @Inject (class case)', () => {
expect(() => createInjector([NoAnnotations]))
.toThrowError(
'Cannot resolve all parameters for \'NoAnnotations\'(?). ' +
"Cannot resolve all parameters for 'NoAnnotations'(?). " +
'Make sure that all the parameters are decorated with Inject or have valid type annotations ' +
'and that \'NoAnnotations\' is decorated with Injectable.');
"and that 'NoAnnotations' is decorated with Injectable.");
});
it('should throw when no type and not @Inject (factory case)', () => {
expect(() => createInjector([provide('someToken', {useFactory: factoryFn})]))
expect(() => createInjector([provide("someToken", {useFactory: factoryFn})]))
.toThrowError(
'Cannot resolve all parameters for \'factoryFn\'(?). ' +
"Cannot resolve all parameters for 'factoryFn'(?). " +
'Make sure that all the parameters are decorated with Inject or have valid type annotations ' +
'and that \'factoryFn\' is decorated with Injectable.');
"and that 'factoryFn' is decorated with Injectable.");
});
it('should cache instances', () => {
@@ -147,10 +172,10 @@ export function main() {
});
it('should provide to a value', () => {
var injector = createInjector([provide(Engine, {useValue: 'fake engine'})]);
var injector = createInjector([provide(Engine, {useValue: "fake engine"})]);
var engine = injector.get(Engine);
expect(engine).toEqual('fake engine');
expect(engine).toEqual("fake engine");
});
it('should provide to a factory', () => {
@@ -168,22 +193,42 @@ export function main() {
function factoryWithTooManyArgs() { return new Car(null); }
var injector = createInjector([
Engine, provide(Car, {
useFactory: factoryWithTooManyArgs,
deps: [
Engine, Engine, Engine, Engine, Engine, Engine, Engine,
Engine, Engine, Engine, Engine, Engine, Engine, Engine,
Engine, Engine, Engine, Engine, Engine, Engine, Engine
]
})
Engine,
provide(Car,
{
useFactory: factoryWithTooManyArgs,
deps: [
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine,
Engine
]
})
]);
try {
injector.get(Car);
throw 'Must throw';
throw "Must throw";
} catch (e) {
expect(e.message).toContain(
`Cannot instantiate 'Car' because it has more than 20 dependencies`);
expect(e.message)
.toContain(`Cannot instantiate 'Car' because it has more than 20 dependencies`);
}
});
@@ -195,7 +240,8 @@ export function main() {
it('should provide to an alias', () => {
var injector = createInjector([
Engine, provide(SportsCar, {useClass: SportsCar}),
Engine,
provide(SportsCar, {useClass: SportsCar}),
provide(Car, {useExisting: SportsCar})
]);
@@ -207,7 +253,8 @@ export function main() {
it('should support multiProviders', () => {
var injector = createInjector([
Engine, new Provider(Car, {useClass: SportsCar, multi: true}),
Engine,
new Provider(Car, {useClass: SportsCar, multi: true}),
new Provider(Car, {useClass: CarWithOptionalEngine, multi: true})
]);
@@ -235,7 +282,7 @@ export function main() {
it('should handle forwardRef in useExisting', () => {
var injector = createInjector([
provide('originalEngine', {useClass: forwardRef(() => Engine)}),
provide('aliasedEngine', {useExisting: <any>forwardRef(() => 'originalEngine')})
provide('aliasedEngine', {useExisting:<any>forwardRef(() => 'originalEngine')})
]);
expect(injector.get('aliasedEngine')).toBeAnInstanceOf(Engine);
});
@@ -256,14 +303,14 @@ export function main() {
expect(car.engine).toEqual(null);
});
it('should flatten passed-in providers', () => {
it("should flatten passed-in providers", () => {
var injector = createInjector([[[Engine, Car]]]);
var car = injector.get(Car);
expect(car).toBeAnInstanceOf(Car);
});
it('should use the last provider when there are multiple providers for same token', () => {
it("should use the last provider when there are multiple providers for same token", () => {
var injector = createInjector(
[provide(Engine, {useClass: Engine}), provide(Engine, {useClass: TurboEngine})]);
@@ -277,7 +324,7 @@ export function main() {
});
it('should throw when given invalid providers', () => {
expect(() => createInjector(<any>['blah']))
expect(() => createInjector(<any>["blah"]))
.toThrowError(
'Invalid provider - only instances of Provider and Type are allowed, got: blah');
});
@@ -319,10 +366,10 @@ export function main() {
try {
injector.get(Car);
throw 'Must throw';
throw "Must throw";
} catch (e) {
expect(e.message).toContain(
`Error during instantiation of Engine! (${stringify(Car)} -> Engine)`);
expect(e.message)
.toContain(`Error during instantiation of Engine! (${stringify(Car)} -> Engine)`);
expect(e.originalException instanceof BaseException).toBeTruthy();
expect(e.causeKey.token).toEqual(Engine);
}
@@ -337,14 +384,14 @@ export function main() {
var protoChild =
new ProtoInjector([new ProviderWithVisibility(carProvider, Visibility.Public)]);
var parent = new Injector(protoParent, null, false, null, () => 'parentContext');
var child = new Injector(protoChild, parent, false, null, () => 'childContext');
var parent = new Injector(protoParent, null, false, null, () => "parentContext");
var child = new Injector(protoChild, parent, false, null, () => "childContext");
try {
child.get(Car);
throw 'Must throw';
throw "Must throw";
} catch (e) {
expect(e.context).toEqual('childContext');
expect(e.context).toEqual("childContext");
}
});
@@ -356,7 +403,7 @@ export function main() {
provide(Engine, {useFactory: (() => isBroken ? new BrokenEngine() : new Engine())})
]);
expect(() => injector.get(Car)).toThrowError(new RegExp('Error'));
expect(() => injector.get(Car)).toThrowError(new RegExp("Error"));
isBroken = false;
@@ -372,7 +419,7 @@ export function main() {
var e = new Engine();
var depProvider = <any>new SpyDependencyProvider();
depProvider.spy('getDependency').andReturn(e);
depProvider.spy("getDependency").andReturn(e);
var providers = Injector.resolve([Car]);
var proto =
@@ -380,14 +427,14 @@ export function main() {
var injector = new Injector(proto, null, false, depProvider);
expect(injector.get(Car).engine).toEqual(e);
expect(depProvider.spy('getDependency'))
.toHaveBeenCalledWith(
injector, providers[0], providers[0].resolvedFactories[0].dependencies[0]);
expect(depProvider.spy("getDependency"))
.toHaveBeenCalledWith(injector, providers[0],
providers[0].resolvedFactories[0].dependencies[0]);
});
});
describe('child', () => {
describe("child", () => {
it('should load instances from parent injector', () => {
var parent = Injector.resolveAndCreate([Engine]);
var child = parent.resolveAndCreateChild([]);
@@ -398,7 +445,7 @@ export function main() {
expect(engineFromChild).toBe(engineFromParent);
});
it('should not use the child providers when resolving the dependencies of a parent provider',
it("should not use the child providers when resolving the dependencies of a parent provider",
() => {
var parent = Injector.resolveAndCreate([Car, Engine]);
var child = parent.resolveAndCreateChild([provide(Engine, {useClass: TurboEngine})]);
@@ -418,7 +465,7 @@ export function main() {
expect(engineFromChild).toBeAnInstanceOf(TurboEngine);
});
it('should give access to parent', () => {
it("should give access to parent", () => {
var parent = Injector.resolveAndCreate([]);
var child = parent.resolveAndCreateChild([]);
expect(child.parent).toBe(parent);
@@ -449,9 +496,9 @@ export function main() {
});
});
describe('depedency resolution', () => {
describe('@Self()', () => {
it('should return a dependency from self', () => {
describe("depedency resolution", () => {
describe("@Self()", () => {
it("should return a dependency from self", () => {
var inj = Injector.resolveAndCreate([
Engine,
provide(Car, {useFactory: (e) => new Car(e), deps: [[Engine, new SelfMetadata()]]})
@@ -460,26 +507,28 @@ export function main() {
expect(inj.get(Car)).toBeAnInstanceOf(Car);
});
it('should throw when not requested provider on self', () => {
it("should throw when not requested provider on self", () => {
var parent = Injector.resolveAndCreate([Engine]);
var child = parent.resolveAndCreateChild([provide(
Car, {useFactory: (e) => new Car(e), deps: [[Engine, new SelfMetadata()]]})]);
var child = parent.resolveAndCreateChild([
provide(Car, {useFactory: (e) => new Car(e), deps: [[Engine, new SelfMetadata()]]})
]);
expect(() => child.get(Car))
.toThrowError(`No provider for Engine! (${stringify(Car)} -> ${stringify(Engine)})`);
});
});
describe('@Host()', () => {
it('should return a dependency from same host', () => {
describe("@Host()", () => {
it("should return a dependency from same host", () => {
var parent = Injector.resolveAndCreate([Engine]);
var child = parent.resolveAndCreateChild([provide(
Car, {useFactory: (e) => new Car(e), deps: [[Engine, new HostMetadata()]]})]);
var child = parent.resolveAndCreateChild([
provide(Car, {useFactory: (e) => new Car(e), deps: [[Engine, new HostMetadata()]]})
]);
expect(child.get(Car)).toBeAnInstanceOf(Car);
});
it('should return a private dependency declared at the host', () => {
it("should return a private dependency declared at the host", () => {
var engine = Injector.resolve([Engine])[0];
var protoParent =
new ProtoInjector([new ProviderWithVisibility(engine, Visibility.Private)]);
@@ -492,7 +541,7 @@ export function main() {
expect(child.get(Car)).toBeAnInstanceOf(Car);
});
it('should not return a public dependency declared at the host', () => {
it("should not return a public dependency declared at the host", () => {
var engine = Injector.resolve([Engine])[0];
var protoParent =
new ProtoInjector([new ProviderWithVisibility(engine, Visibility.Public)]);
@@ -506,7 +555,7 @@ export function main() {
.toThrowError(`No provider for Engine! (${stringify(Car)} -> ${stringify(Engine)})`);
});
it('should not skip self', () => {
it("should not skip self", () => {
var parent = Injector.resolveAndCreate([Engine]);
var child = parent.resolveAndCreateChild([
provide(Engine, {useClass: TurboEngine}),
@@ -517,8 +566,8 @@ export function main() {
});
});
describe('default', () => {
it('should return a private dependency declared at the host', () => {
describe("default", () => {
it("should return a private dependency declared at the host", () => {
var engine = Injector.resolve([Engine])[0];
var protoParent =
new ProtoInjector([new ProviderWithVisibility(engine, Visibility.Private)]);
@@ -527,16 +576,15 @@ export function main() {
var child = createInjector(
[
provide(Engine, {useClass: BrokenEngine}),
provide(
Car,
{useFactory: (e) => new Car(e), deps: [[Engine, new SkipSelfMetadata()]]})
provide(Car,
{useFactory: (e) => new Car(e), deps: [[Engine, new SkipSelfMetadata()]]})
],
parent, true); // boundary
expect(child.get(Car)).toBeAnInstanceOf(Car);
});
it('should return a public dependency declared at the host', () => {
it("should return a public dependency declared at the host", () => {
var engine = Injector.resolve([Engine])[0];
var protoParent =
new ProtoInjector([new ProviderWithVisibility(engine, Visibility.Public)]);
@@ -545,16 +593,15 @@ export function main() {
var child = createInjector(
[
provide(Engine, {useClass: BrokenEngine}),
provide(
Car,
{useFactory: (e) => new Car(e), deps: [[Engine, new SkipSelfMetadata()]]})
provide(Car,
{useFactory: (e) => new Car(e), deps: [[Engine, new SkipSelfMetadata()]]})
],
parent, true); // boundary
expect(child.get(Car)).toBeAnInstanceOf(Car);
});
it('should not return a private dependency declared NOT at the host', () => {
it("should not return a private dependency declared NOT at the host", () => {
var engine = Injector.resolve([Engine])[0];
var protoParent =
new ProtoInjector([new ProviderWithVisibility(engine, Visibility.Private)]);
@@ -563,9 +610,8 @@ export function main() {
var child = createInjector(
[
provide(Engine, {useClass: BrokenEngine}),
provide(
Car,
{useFactory: (e) => new Car(e), deps: [[Engine, new SkipSelfMetadata()]]})
provide(Car,
{useFactory: (e) => new Car(e), deps: [[Engine, new SkipSelfMetadata()]]})
],
parent, false);
@@ -573,7 +619,7 @@ export function main() {
.toThrowError(`No provider for Engine! (${stringify(Car)} -> ${stringify(Engine)})`);
});
it('should not skip self', () => {
it("should not skip self", () => {
var parent = Injector.resolveAndCreate([Engine]);
var child = parent.resolveAndCreateChild([
provide(Engine, {useClass: TurboEngine}),
@@ -594,7 +640,7 @@ export function main() {
});
});
it('should support multi providers', () => {
it("should support multi providers", () => {
var provider = Injector.resolve([
new Provider(Engine, {useClass: BrokenEngine, multi: true}),
new Provider(Engine, {useClass: TurboEngine, multi: true})
@@ -605,7 +651,7 @@ export function main() {
expect(provider.resolvedFactories.length).toEqual(2);
});
it('should support multi providers with only one provider', () => {
it("should support multi providers with only one provider", () => {
var provider =
Injector.resolve([new Provider(Engine, {useClass: BrokenEngine, multi: true})])[0];
@@ -614,23 +660,22 @@ export function main() {
expect(provider.resolvedFactories.length).toEqual(1);
});
it('should throw when mixing multi providers with regular providers', () => {
it("should throw when mixing multi providers with regular providers", () => {
expect(() => {
Injector.resolve([new Provider(Engine, {useClass: BrokenEngine, multi: true}), Engine]);
}).toThrowErrorWith('Cannot mix multi providers and regular providers');
}).toThrowErrorWith("Cannot mix multi providers and regular providers");
expect(() => {
Injector.resolve([Engine, new Provider(Engine, {useClass: BrokenEngine, multi: true})]);
}).toThrowErrorWith('Cannot mix multi providers and regular providers');
}).toThrowErrorWith("Cannot mix multi providers and regular providers");
});
it('should resolve forward references', () => {
var providers = Injector.resolve([
forwardRef(() => Engine),
[provide(forwardRef(() => BrokenEngine), {useClass: forwardRef(() => Engine)})],
provide(
forwardRef(() => String),
{useFactory: () => 'OK', deps: [forwardRef(() => Engine)]})
provide(forwardRef(() => String),
{useFactory: () => 'OK', deps: [forwardRef(() => Engine)]})
]);
var engineProvider = providers[0];
@@ -643,33 +688,35 @@ export function main() {
});
it('should support overriding factory dependencies with dependency annotations', () => {
var providers = Injector.resolve([provide('token', {
useFactory: (e) => 'result',
deps: [[new InjectMetadata('dep'), new CustomDependencyMetadata()]]
})]);
var providers = Injector.resolve([
provide("token",
{
useFactory: (e) => "result",
deps: [[new InjectMetadata("dep"), new CustomDependencyMetadata()]]
})
]);
var provider = providers[0];
expect(provider.resolvedFactories[0].dependencies[0].key.token).toEqual('dep');
expect(provider.resolvedFactories[0].dependencies[0].properties).toEqual([
new CustomDependencyMetadata()
]);
expect(provider.resolvedFactories[0].dependencies[0].key.token).toEqual("dep");
expect(provider.resolvedFactories[0].dependencies[0].properties)
.toEqual([new CustomDependencyMetadata()]);
});
it('should allow declaring dependencies with flat arrays', () => {
var resolved = Injector.resolve(
[provide('token', {useFactory: e => e, deps: [new InjectMetadata('dep')]})]);
[provide('token', {useFactory: e => e, deps: [new InjectMetadata("dep")]})]);
var nestedResolved = Injector.resolve(
[provide('token', {useFactory: e => e, deps: [[new InjectMetadata('dep')]]})]);
[provide('token', {useFactory: e => e, deps: [[new InjectMetadata("dep")]]})]);
expect(resolved[0].resolvedFactories[0].dependencies[0].key.token)
.toEqual(nestedResolved[0].resolvedFactories[0].dependencies[0].key.token);
});
});
describe('displayName', () => {
it('should work', () => {
describe("displayName", () => {
it("should work", () => {
expect(Injector.resolveAndCreate([Engine, BrokenEngine]).displayName)
.toEqual('Injector(providers: [ \'Engine\' , \'BrokenEngine\' ])');
.toEqual('Injector(providers: [ "Engine" , "BrokenEngine" ])');
});
});
});
+1 -1
View File
@@ -2,7 +2,7 @@ import {describe, iit, it, expect, beforeEach} from 'angular2/testing_internal';
import {Key, KeyRegistry} from 'angular2/src/core/di/key';
export function main() {
describe('key', function() {
describe("key", function() {
var registry: KeyRegistry;
beforeEach(function() { registry = new KeyRegistry(); });
@@ -1,38 +1,58 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit, Log, TestComponentBuilder} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xdescribe,
xit,
Log,
TestComponentBuilder
} from 'angular2/testing_internal';
import {OnChanges, OnInit, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked} from 'angular2/core';
import {
OnChanges,
OnInit,
DoCheck,
AfterContentInit,
AfterContentChecked,
AfterViewInit,
AfterViewChecked
} from 'angular2/core';
import {Directive, Component, ViewMetadata} from 'angular2/src/core/metadata';
export function main() {
describe('directive lifecycle integration spec', () => {
it('should invoke lifecycle methods ngOnChanges > ngOnInit > ngDoCheck > ngAfterContentChecked',
inject(
[TestComponentBuilder, Log, AsyncTestCompleter],
(tcb: TestComponentBuilder, log: Log, async) => {
tcb.overrideView(MyComp, new ViewMetadata({
template: '<div [field]="123" lifecycle></div>',
directives: [LifecycleCmp]
}))
.createAsync(MyComp)
.then((tc) => {
tc.detectChanges();
inject([TestComponentBuilder, Log, AsyncTestCompleter], (tcb: TestComponentBuilder, log: Log,
async) => {
tcb.overrideView(
MyComp,
new ViewMetadata(
{template: '<div [field]="123" lifecycle></div>', directives: [LifecycleCmp]}))
.createAsync(MyComp)
.then((tc) => {
tc.detectChanges();
expect(log.result())
.toEqual(
'ngOnChanges; ngOnInit; ngDoCheck; ngAfterContentInit; ngAfterContentChecked; child_ngDoCheck; ' +
'ngAfterViewInit; ngAfterViewChecked');
expect(log.result())
.toEqual(
"ngOnChanges; ngOnInit; ngDoCheck; ngAfterContentInit; ngAfterContentChecked; child_ngDoCheck; " +
"ngAfterViewInit; ngAfterViewChecked");
log.clear();
tc.detectChanges();
log.clear();
tc.detectChanges();
expect(log.result())
.toEqual(
'ngDoCheck; ngAfterContentChecked; child_ngDoCheck; ngAfterViewChecked');
expect(log.result())
.toEqual(
"ngDoCheck; ngAfterContentChecked; child_ngDoCheck; ngAfterViewChecked");
async.done();
});
}));
async.done();
});
}));
});
}
@@ -40,11 +60,11 @@ export function main() {
@Directive({selector: '[lifecycle-dir]'})
class LifecycleDir implements DoCheck {
constructor(private _log: Log) {}
ngDoCheck() { this._log.add('child_ngDoCheck'); }
ngDoCheck() { this._log.add("child_ngDoCheck"); }
}
@Component({
selector: '[lifecycle]',
selector: "[lifecycle]",
inputs: ['field'],
template: `<div lifecycle-dir></div>`,
directives: [LifecycleDir]
@@ -54,19 +74,19 @@ class LifecycleCmp implements OnChanges,
field;
constructor(private _log: Log) {}
ngOnChanges(_) { this._log.add('ngOnChanges'); }
ngOnChanges(_) { this._log.add("ngOnChanges"); }
ngOnInit() { this._log.add('ngOnInit'); }
ngOnInit() { this._log.add("ngOnInit"); }
ngDoCheck() { this._log.add('ngDoCheck'); }
ngDoCheck() { this._log.add("ngDoCheck"); }
ngAfterContentInit() { this._log.add('ngAfterContentInit'); }
ngAfterContentInit() { this._log.add("ngAfterContentInit"); }
ngAfterContentChecked() { this._log.add('ngAfterContentChecked'); }
ngAfterContentChecked() { this._log.add("ngAfterContentChecked"); }
ngAfterViewInit() { this._log.add('ngAfterViewInit'); }
ngAfterViewInit() { this._log.add("ngAfterViewInit"); }
ngAfterViewChecked() { this._log.add('ngAfterViewChecked'); }
ngAfterViewChecked() { this._log.add("ngAfterViewChecked"); }
}
@Component({selector: 'my-comp', directives: []})
@@ -1,4 +1,18 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, el, expect, iit, inject, it, xit, beforeEachProviders, SpyObject, stringifyElement} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit,
beforeEachProviders,
SpyObject,
stringifyElement
} from 'angular2/testing_internal';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
+12 -1
View File
@@ -1,4 +1,15 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, el, expect, iit, inject, it, xit} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit
} from 'angular2/testing_internal';
export function main() {
describe('Shim', () => {
@@ -1,12 +1,24 @@
import {describe, it, expect, beforeEach, ddescribe, iit, xit, el, SpyObject, AsyncTestCompleter, inject} from 'angular2/testing_internal';
import {
describe,
it,
expect,
beforeEach,
ddescribe,
iit,
xit,
el,
SpyObject,
AsyncTestCompleter,
inject
} from 'angular2/testing_internal';
import {Observable, Subject, EventEmitter, PromiseWrapper} from 'angular2/src/facade/async';
export function main() {
describe('Observable', () => {
describe('#core', () => {
describe("Observable", () => {
describe("#core", () => {
it('should call next with values', inject([AsyncTestCompleter], (async) => {
it("should call next with values", inject([AsyncTestCompleter], (async) => {
let o = new Observable(sink => { sink.next(1); });
@@ -17,7 +29,7 @@ export function main() {
}));
it('should call next and then complete', inject([AsyncTestCompleter], (async) => {
it("should call next and then complete", inject([AsyncTestCompleter], (async) => {
let o = new Observable(sink => {
sink.next(1);
@@ -25,16 +37,14 @@ export function main() {
});
let nexted = false;
o.subscribe(
v => { nexted = true; }, null,
() => {
expect(nexted).toBe(true);
async.done();
});
o.subscribe(v => { nexted = true; }, null, () => {
expect(nexted).toBe(true);
async.done();
});
}));
it('should call error with errors', inject([AsyncTestCompleter], (async) => {
it("should call error with errors", inject([AsyncTestCompleter], (async) => {
let o = new Observable(sink => { sink.error('oh noes!'); });
@@ -1,11 +1,32 @@
import {AsyncTestCompleter, TestComponentBuilder, beforeEach, ddescribe, describe, expect, iit, inject, it, xit} from 'angular2/testing_internal';
import {bind, provide, forwardRef, resolveForwardRef, Component, Directive, Inject, Query, QueryList} from 'angular2/core';
import {
AsyncTestCompleter,
TestComponentBuilder,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit
} from 'angular2/testing_internal';
import {
bind,
provide,
forwardRef,
resolveForwardRef,
Component,
Directive,
Inject,
Query,
QueryList
} from 'angular2/core';
import {NgFor} from 'angular2/common';
import {Type} from 'angular2/src/facade/lang';
import {asNativeElements} from 'angular2/core';
export function main() {
describe('forwardRef integration', function() {
describe("forwardRef integration", function() {
it('should instantiate components which are declared using forwardRef',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(App).then((tc) => {
@@ -35,9 +56,8 @@ class Door {
locks: QueryList<Lock>;
frame: Frame;
constructor(
@Query(forwardRef(() => Lock)) locks: QueryList<Lock>,
@Inject(forwardRef(() => Frame)) frame: Frame) {
constructor(@Query(forwardRef(() => Lock)) locks: QueryList<Lock>,
@Inject(forwardRef(() => Frame)) frame: Frame) {
this.frame = frame;
this.locks = locks;
}
@@ -1,9 +1,22 @@
import {ddescribe, describe, xdescribe, it, iit, xit, expect, beforeEach, afterEach, AsyncTestCompleter, inject, beforeEachProviders} from 'angular2/testing_internal';
import {
ddescribe,
describe,
xdescribe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
AsyncTestCompleter,
inject,
beforeEachProviders
} from 'angular2/testing_internal';
import {provide} from 'angular2/core';
import {Compiler} from 'angular2/src/core/linker/compiler';
import {reflector, ReflectionInfo} from 'angular2/src/core/reflection/reflection';
import {Compiler_} from 'angular2/src/core/linker/compiler';
import {Compiler_} from "angular2/src/core/linker/compiler";
import {HostViewFactory} from 'angular2/src/core/linker/view';
import {HostViewFactoryRef_} from 'angular2/src/core/linker/view_ref';
@@ -20,11 +33,12 @@ export function main() {
it('should read the template from an annotation',
inject([AsyncTestCompleter, Compiler], (async, compiler: Compiler) => {
compiler.compileInHost(SomeComponent).then((hostViewFactoryRef: HostViewFactoryRef_) => {
expect(hostViewFactoryRef.internalHostViewFactory).toBe(someHostViewFactory);
async.done();
return null;
});
compiler.compileInHost(SomeComponent)
.then((hostViewFactoryRef: HostViewFactoryRef_) => {
expect(hostViewFactoryRef.internalHostViewFactory).toBe(someHostViewFactory);
async.done();
return null;
});
}));
it('should clear the cache', inject([Compiler], (compiler) => {
@@ -1,4 +1,17 @@
import {AsyncTestCompleter, beforeEach, xdescribe, ddescribe, describe, el, expect, iit, inject, it, SpyObject, proxy} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
xdescribe,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
SpyObject,
proxy
} from 'angular2/testing_internal';
import {hasLifecycleHook} from 'angular2/src/core/linker/directive_lifecycle_reflector';
import {LifecycleHooks} from 'angular2/src/core/linker/interfaces';
@@ -7,93 +20,93 @@ export function main() {
describe('Create DirectiveMetadata', () => {
describe('lifecycle', () => {
describe('ngOnChanges', () => {
it('should be true when the directive has the ngOnChanges method', () => {
describe("ngOnChanges", () => {
it("should be true when the directive has the ngOnChanges method", () => {
expect(hasLifecycleHook(LifecycleHooks.OnChanges, DirectiveWithOnChangesMethod))
.toBe(true);
});
it('should be false otherwise', () => {
it("should be false otherwise", () => {
expect(hasLifecycleHook(LifecycleHooks.OnChanges, DirectiveNoHooks)).toBe(false);
});
});
describe('ngOnDestroy', () => {
it('should be true when the directive has the ngOnDestroy method', () => {
describe("ngOnDestroy", () => {
it("should be true when the directive has the ngOnDestroy method", () => {
expect(hasLifecycleHook(LifecycleHooks.OnDestroy, DirectiveWithOnDestroyMethod))
.toBe(true);
});
it('should be false otherwise', () => {
it("should be false otherwise", () => {
expect(hasLifecycleHook(LifecycleHooks.OnDestroy, DirectiveNoHooks)).toBe(false);
});
});
describe('ngOnInit', () => {
it('should be true when the directive has the ngOnInit method', () => {
describe("ngOnInit", () => {
it("should be true when the directive has the ngOnInit method", () => {
expect(hasLifecycleHook(LifecycleHooks.OnInit, DirectiveWithOnInitMethod)).toBe(true);
});
it('should be false otherwise', () => {
it("should be false otherwise", () => {
expect(hasLifecycleHook(LifecycleHooks.OnInit, DirectiveNoHooks)).toBe(false);
});
});
describe('ngDoCheck', () => {
it('should be true when the directive has the ngDoCheck method', () => {
describe("ngDoCheck", () => {
it("should be true when the directive has the ngDoCheck method", () => {
expect(hasLifecycleHook(LifecycleHooks.DoCheck, DirectiveWithOnCheckMethod)).toBe(true);
});
it('should be false otherwise', () => {
it("should be false otherwise", () => {
expect(hasLifecycleHook(LifecycleHooks.DoCheck, DirectiveNoHooks)).toBe(false);
});
});
describe('ngAfterContentInit', () => {
it('should be true when the directive has the ngAfterContentInit method', () => {
expect(hasLifecycleHook(
LifecycleHooks.AfterContentInit, DirectiveWithAfterContentInitMethod))
describe("ngAfterContentInit", () => {
it("should be true when the directive has the ngAfterContentInit method", () => {
expect(hasLifecycleHook(LifecycleHooks.AfterContentInit,
DirectiveWithAfterContentInitMethod))
.toBe(true);
});
it('should be false otherwise', () => {
it("should be false otherwise", () => {
expect(hasLifecycleHook(LifecycleHooks.AfterContentInit, DirectiveNoHooks)).toBe(false);
});
});
describe('ngAfterContentChecked', () => {
it('should be true when the directive has the ngAfterContentChecked method', () => {
expect(hasLifecycleHook(
LifecycleHooks.AfterContentChecked, DirectiveWithAfterContentCheckedMethod))
describe("ngAfterContentChecked", () => {
it("should be true when the directive has the ngAfterContentChecked method", () => {
expect(hasLifecycleHook(LifecycleHooks.AfterContentChecked,
DirectiveWithAfterContentCheckedMethod))
.toBe(true);
});
it('should be false otherwise', () => {
it("should be false otherwise", () => {
expect(hasLifecycleHook(LifecycleHooks.AfterContentChecked, DirectiveNoHooks))
.toBe(false);
});
});
describe('ngAfterViewInit', () => {
it('should be true when the directive has the ngAfterViewInit method', () => {
describe("ngAfterViewInit", () => {
it("should be true when the directive has the ngAfterViewInit method", () => {
expect(hasLifecycleHook(LifecycleHooks.AfterViewInit, DirectiveWithAfterViewInitMethod))
.toBe(true);
});
it('should be false otherwise', () => {
it("should be false otherwise", () => {
expect(hasLifecycleHook(LifecycleHooks.AfterViewInit, DirectiveNoHooks)).toBe(false);
});
});
describe('ngAfterViewChecked', () => {
it('should be true when the directive has the ngAfterViewChecked method', () => {
expect(hasLifecycleHook(
LifecycleHooks.AfterViewChecked, DirectiveWithAfterViewCheckedMethod))
describe("ngAfterViewChecked", () => {
it("should be true when the directive has the ngAfterViewChecked method", () => {
expect(hasLifecycleHook(LifecycleHooks.AfterViewChecked,
DirectiveWithAfterViewCheckedMethod))
.toBe(true);
});
it('should be false otherwise', () => {
it("should be false otherwise", () => {
expect(hasLifecycleHook(LifecycleHooks.AfterViewChecked, DirectiveNoHooks)).toBe(false);
});
});
@@ -1,6 +1,21 @@
import {ddescribe, describe, it, iit, expect, beforeEach} from 'angular2/testing_internal';
import {DirectiveResolver} from 'angular2/src/core/linker/directive_resolver';
import {DirectiveMetadata, Directive, Input, Output, HostBinding, HostListener, ContentChildren, ContentChildrenMetadata, ViewChildren, ViewChildrenMetadata, ContentChild, ContentChildMetadata, ViewChild, ViewChildMetadata} from 'angular2/src/core/metadata';
import {
DirectiveMetadata,
Directive,
Input,
Output,
HostBinding,
HostListener,
ContentChildren,
ContentChildrenMetadata,
ViewChildren,
ViewChildrenMetadata,
ContentChild,
ContentChildMetadata,
ViewChild,
ViewChildMetadata
} from 'angular2/src/core/metadata';
@Directive({selector: 'someDirective'})
class SomeDirective {
@@ -13,14 +28,14 @@ class SomeChildDirective extends SomeDirective {
@Directive({selector: 'someDirective', inputs: ['c']})
class SomeDirectiveWithInputs {
@Input() a;
@Input('renamed') b;
@Input("renamed") b;
c;
}
@Directive({selector: 'someDirective', outputs: ['c']})
class SomeDirectiveWithOutputs {
@Output() a;
@Output('renamed') b;
@Output("renamed") b;
c;
}
@@ -40,59 +55,64 @@ class SomeDirectiveWithEvents {
@Directive({selector: 'someDirective'})
class SomeDirectiveWithSetterProps {
@Input('renamed')
set a(value) {}
@Input("renamed")
set a(value) {
}
}
@Directive({selector: 'someDirective'})
class SomeDirectiveWithGetterOutputs {
@Output('renamed')
get a() { return null; }
@Output("renamed")
get a() {
return null;
}
}
@Directive({selector: 'someDirective', host: {'[c]': 'c'}})
class SomeDirectiveWithHostBindings {
@HostBinding() a;
@HostBinding('renamed') b;
@HostBinding("renamed") b;
c;
}
@Directive({selector: 'someDirective', host: {'(c)': 'onC()'}})
class SomeDirectiveWithHostListeners {
@HostListener('a')
onA() {}
onA() {
}
@HostListener('b', ['$event.value'])
onB(value) {}
onB(value) {
}
}
@Directive({selector: 'someDirective', queries: {'cs': new ContentChildren('c')}})
@Directive({selector: 'someDirective', queries: {"cs": new ContentChildren("c")}})
class SomeDirectiveWithContentChildren {
@ContentChildren('a') as: any;
@ContentChildren("a") as: any;
c;
}
@Directive({selector: 'someDirective', queries: {'cs': new ViewChildren('c')}})
@Directive({selector: 'someDirective', queries: {"cs": new ViewChildren("c")}})
class SomeDirectiveWithViewChildren {
@ViewChildren('a') as: any;
@ViewChildren("a") as: any;
c;
}
@Directive({selector: 'someDirective', queries: {'c': new ContentChild('c')}})
@Directive({selector: 'someDirective', queries: {"c": new ContentChild("c")}})
class SomeDirectiveWithContentChild {
@ContentChild('a') a: any;
@ContentChild("a") a: any;
c;
}
@Directive({selector: 'someDirective', queries: {'c': new ViewChild('c')}})
@Directive({selector: 'someDirective', queries: {"c": new ViewChild("c")}})
class SomeDirectiveWithViewChild {
@ViewChild('a') a: any;
@ViewChild("a") a: any;
c;
}
class SomeDirectiveWithoutMetadata {}
export function main() {
describe('DirectiveResolver', () => {
describe("DirectiveResolver", () => {
var resolver: DirectiveResolver;
beforeEach(() => { resolver = new DirectiveResolver(); });
@@ -105,9 +125,8 @@ export function main() {
});
it('should throw if not matching metadata is found', () => {
expect(() => {
resolver.resolve(SomeDirectiveWithoutMetadata);
}).toThrowError('No Directive annotation found on SomeDirectiveWithoutMetadata');
expect(() => { resolver.resolve(SomeDirectiveWithoutMetadata); })
.toThrowError('No Directive annotation found on SomeDirectiveWithoutMetadata');
});
it('should not read parent class Directive metadata', function() {
@@ -165,25 +184,25 @@ export function main() {
it('should append ContentChildren', () => {
var directiveMetadata = resolver.resolve(SomeDirectiveWithContentChildren);
expect(directiveMetadata.queries)
.toEqual({'cs': new ContentChildren('c'), 'as': new ContentChildren('a')});
.toEqual({"cs": new ContentChildren("c"), "as": new ContentChildren("a")});
});
it('should append ViewChildren', () => {
var directiveMetadata = resolver.resolve(SomeDirectiveWithViewChildren);
expect(directiveMetadata.queries)
.toEqual({'cs': new ViewChildren('c'), 'as': new ViewChildren('a')});
.toEqual({"cs": new ViewChildren("c"), "as": new ViewChildren("a")});
});
it('should append ContentChild', () => {
var directiveMetadata = resolver.resolve(SomeDirectiveWithContentChild);
expect(directiveMetadata.queries)
.toEqual({'c': new ContentChild('c'), 'a': new ContentChild('a')});
.toEqual({"c": new ContentChild("c"), "a": new ContentChild("a")});
});
it('should append ViewChild', () => {
var directiveMetadata = resolver.resolve(SomeDirectiveWithViewChild);
expect(directiveMetadata.queries)
.toEqual({'c': new ViewChild('c'), 'a': new ViewChild('a')});
.toEqual({"c": new ViewChild("c"), "a": new ViewChild("a")});
});
});
});
@@ -1,4 +1,20 @@
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, el, dispatchEvent, expect, iit, inject, beforeEachProviders, it, xit, TestComponentBuilder, ComponentFixture} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
xdescribe,
describe,
el,
dispatchEvent,
expect,
iit,
inject,
beforeEachProviders,
it,
xit,
TestComponentBuilder,
ComponentFixture
} from 'angular2/testing_internal';
import {OnDestroy} from 'angular2/core';
import {Injector} from 'angular2/core';
@@ -8,48 +24,50 @@ import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component
import {ElementRef, ElementRef_} from 'angular2/src/core/linker/element_ref';
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {ComponentFixture_} from 'angular2/src/testing/test_component_builder';
import {ComponentFixture_} from "angular2/src/testing/test_component_builder";
import {BaseException} from 'angular2/src/facade/exceptions';
import {PromiseWrapper} from 'angular2/src/facade/promise';
import {stringify} from 'angular2/src/facade/lang';
export function main() {
describe('DynamicComponentLoader', function() {
describe('loading into a location', () => {
describe("loading into a location", () => {
it('should work',
inject(
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(
MyComp, new ViewMetadata(
{template: '<location #loc></location>', directives: [Location]}))
.createAsync(MyComp)
.then((tc) => {
loader.loadIntoLocation(DynamicallyLoaded, tc.elementRef, 'loc').then(ref => {
expect(tc.debugElement.nativeElement)
.toHaveText('Location;DynamicallyLoaded;');
async.done();
});
});
}));
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(
MyComp,
new ViewMetadata(
{template: '<location #loc></location>', directives: [Location]}))
.createAsync(MyComp)
.then((tc) => {
loader.loadIntoLocation(DynamicallyLoaded, tc.elementRef, 'loc')
.then(ref => {
expect(tc.debugElement.nativeElement)
.toHaveText("Location;DynamicallyLoaded;");
async.done();
});
});
}));
it('should return a disposable component ref',
inject(
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(
MyComp, new ViewMetadata(
{template: '<location #loc></location>', directives: [Location]}))
.createAsync(MyComp)
.then((tc) => {
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(
MyComp,
new ViewMetadata(
{template: '<location #loc></location>', directives: [Location]}))
.createAsync(MyComp)
.then((tc) => {
loader.loadIntoLocation(DynamicallyLoaded, tc.elementRef, 'loc').then(ref => {
ref.dispose();
expect(tc.debugElement.nativeElement).toHaveText('Location;');
async.done();
});
});
}));
loader.loadIntoLocation(DynamicallyLoaded, tc.elementRef, 'loc')
.then(ref => {
ref.dispose();
expect(tc.debugElement.nativeElement).toHaveText("Location;");
async.done();
});
});
}));
it('should allow to dispose even if the location has been removed',
inject(
@@ -75,14 +93,14 @@ export function main() {
loader.loadIntoLocation(DynamicallyLoaded, childElementRef, 'loc')
.then(ref => {
expect(tc.debugElement.nativeElement)
.toHaveText('Location;DynamicallyLoaded;');
.toHaveText("Location;DynamicallyLoaded;");
tc.debugElement.componentInstance.ctxBoolProp = false;
tc.detectChanges();
expect(tc.debugElement.nativeElement).toHaveText('');
expect(tc.debugElement.nativeElement).toHaveText("");
ref.dispose();
expect(tc.debugElement.nativeElement).toHaveText('');
expect(tc.debugElement.nativeElement).toHaveText("");
async.done();
});
});
@@ -99,89 +117,85 @@ export function main() {
.then((tc) => {
loader.loadIntoLocation(DynamicallyLoadedWithHostProps, tc.elementRef, 'loc')
.then(ref => {
ref.instance.id = 'new value';
ref.instance.id = "new value";
tc.detectChanges();
var newlyInsertedElement =
DOM.childNodes(tc.debugElement.nativeElement)[1];
expect((<HTMLElement>newlyInsertedElement).id).toEqual('new value');
expect((<HTMLElement>newlyInsertedElement).id).toEqual("new value");
async.done();
});
});
}));
it('should leave the view tree in a consistent state if hydration fails',
inject(
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({
template: '<div><location #loc></location></div>',
directives: [Location]
}))
.createAsync(MyComp)
.then((tc: ComponentFixture) => {
tc.debugElement
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({
template: '<div><location #loc></location></div>',
directives: [Location]
}))
.createAsync(MyComp)
.then((tc: ComponentFixture) => {
tc.debugElement
PromiseWrapper.catchError(
loader.loadIntoLocation(DynamicallyLoadedThrows, tc.elementRef, 'loc'),
error => {
expect(error.message).toContain('ThrownInConstructor');
expect(() => tc.detectChanges()).not.toThrow();
async.done();
return null;
});
});
}));
PromiseWrapper.catchError(
loader.loadIntoLocation(DynamicallyLoadedThrows, tc.elementRef,
'loc'),
error => {
expect(error.message).toContain("ThrownInConstructor");
expect(() => tc.detectChanges()).not.toThrow();
async.done();
return null;
});
});
}));
it('should throw if the variable does not exist',
inject(
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(
MyComp, new ViewMetadata(
{template: '<location #loc></location>', directives: [Location]}))
.createAsync(MyComp)
.then((tc) => {
expect(
() => loader.loadIntoLocation(
DynamicallyLoadedWithHostProps, tc.elementRef, 'someUnknownVariable'))
.toThrowError('Could not find variable someUnknownVariable');
async.done();
});
}));
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(
MyComp,
new ViewMetadata(
{template: '<location #loc></location>', directives: [Location]}))
.createAsync(MyComp)
.then((tc) => {
expect(() => loader.loadIntoLocation(DynamicallyLoadedWithHostProps,
tc.elementRef, 'someUnknownVariable'))
.toThrowError('Could not find variable someUnknownVariable');
async.done();
});
}));
it('should allow to pass projectable nodes',
inject(
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(
MyComp, new ViewMetadata({template: '<div #loc></div>', directives: []}))
.createAsync(MyComp)
.then((tc) => {
loader
.loadIntoLocation(
DynamicallyLoadedWithNgContent, tc.elementRef, 'loc', null,
[[DOM.createTextNode('hello')]])
.then(ref => {
tc.detectChanges();
expect(tc.nativeElement).toHaveText('dynamic(hello)');
async.done();
});
});
}));
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp,
new ViewMetadata({template: '<div #loc></div>', directives: []}))
.createAsync(MyComp)
.then((tc) => {
loader.loadIntoLocation(DynamicallyLoadedWithNgContent, tc.elementRef,
'loc', null, [[DOM.createTextNode('hello')]])
.then(ref => {
tc.detectChanges();
expect(tc.nativeElement).toHaveText('dynamic(hello)');
async.done();
});
});
}));
it('should throw if not enough projectable nodes are passed in',
inject(
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(
MyComp, new ViewMetadata({template: '<div #loc></div>', directives: []}))
tcb.overrideView(MyComp,
new ViewMetadata({template: '<div #loc></div>', directives: []}))
.createAsync(MyComp)
.then((tc) => {
PromiseWrapper.catchError(
loader.loadIntoLocation(
DynamicallyLoadedWithNgContent, tc.elementRef, 'loc', null, []),
loader.loadIntoLocation(DynamicallyLoadedWithNgContent, tc.elementRef,
'loc', null, []),
(e) => {
expect(e.message).toContain(
`The component ${stringify(DynamicallyLoadedWithNgContent)} has 1 <ng-content> elements, but only 0 slots were provided`);
@@ -193,157 +207,152 @@ export function main() {
});
describe('loading next to a location', () => {
describe("loading next to a location", () => {
it('should work',
inject(
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({
template: '<div><location #loc></location></div>',
directives: [Location]
}))
.createAsync(MyComp)
.then((tc) => {
loader.loadNextToLocation(DynamicallyLoaded, tc.elementRef).then(ref => {
expect(tc.debugElement.nativeElement).toHaveText('Location;');
expect(DOM.nextSibling(tc.debugElement.nativeElement))
.toHaveText('DynamicallyLoaded;');
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({
template: '<div><location #loc></location></div>',
directives: [Location]
}))
.createAsync(MyComp)
.then((tc) => {
loader.loadNextToLocation(DynamicallyLoaded, tc.elementRef)
.then(ref => {
expect(tc.debugElement.nativeElement).toHaveText("Location;");
expect(DOM.nextSibling(tc.debugElement.nativeElement))
.toHaveText('DynamicallyLoaded;');
async.done();
});
});
}));
async.done();
});
});
}));
it('should return a disposable component ref',
inject(
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({
template: '<div><location #loc></location></div>',
directives: [Location]
}))
.
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({
template: '<div><location #loc></location></div>',
directives: [Location]
}))
.
createAsync(MyComp)
.then((tc) => {
loader.loadNextToLocation(DynamicallyLoaded, tc.elementRef).then(ref => {
loader.loadNextToLocation(DynamicallyLoaded2, tc.elementRef).then(ref2 => {
var firstSibling = DOM.nextSibling(tc.debugElement.nativeElement);
var secondSibling = DOM.nextSibling(firstSibling);
expect(tc.debugElement.nativeElement).toHaveText('Location;');
expect(firstSibling).toHaveText('DynamicallyLoaded;');
expect(secondSibling).toHaveText('DynamicallyLoaded2;');
createAsync(MyComp)
.then((tc) => {
loader.loadNextToLocation(DynamicallyLoaded, tc.elementRef)
.then(ref => {
loader.loadNextToLocation(DynamicallyLoaded2, tc.elementRef)
.then(ref2 => {
var firstSibling =
DOM.nextSibling(tc.debugElement.nativeElement);
var secondSibling = DOM.nextSibling(firstSibling);
expect(tc.debugElement.nativeElement).toHaveText("Location;");
expect(firstSibling).toHaveText("DynamicallyLoaded;");
expect(secondSibling).toHaveText("DynamicallyLoaded2;");
ref2.dispose();
ref2.dispose();
firstSibling = DOM.nextSibling(tc.debugElement.nativeElement);
secondSibling = DOM.nextSibling(firstSibling);
expect(secondSibling).toBeNull();
firstSibling = DOM.nextSibling(tc.debugElement.nativeElement);
secondSibling = DOM.nextSibling(firstSibling);
expect(secondSibling).toBeNull();
async.done();
});
});
});
}));
async.done();
});
});
});
}));
it('should update host properties',
inject(
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({
template: '<div><location #loc></location></div>',
directives: [Location]
}))
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({
template: '<div><location #loc></location></div>',
directives: [Location]
}))
.createAsync(MyComp)
.then((tc) => {
.createAsync(MyComp)
.then((tc) => {
loader.loadNextToLocation(DynamicallyLoadedWithHostProps, tc.elementRef)
.then(ref => {
ref.instance.id = 'new value';
loader.loadNextToLocation(DynamicallyLoadedWithHostProps, tc.elementRef)
.then(ref => {
ref.instance.id = "new value";
tc.detectChanges();
tc.detectChanges();
var newlyInsertedElement =
DOM.nextSibling(tc.debugElement.nativeElement);
expect((<HTMLElement>newlyInsertedElement).id).toEqual('new value');
var newlyInsertedElement =
DOM.nextSibling(tc.debugElement.nativeElement);
expect((<HTMLElement>newlyInsertedElement).id).toEqual("new value");
async.done();
});
});
}));
async.done();
});
});
}));
it('should allow to pass projectable nodes',
inject(
[DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({template: '', directives: [Location]}))
.createAsync(MyComp)
.then((tc) => {
loader
.loadNextToLocation(
DynamicallyLoadedWithNgContent, tc.elementRef, null,
[[DOM.createTextNode('hello')]])
.then(ref => {
tc.detectChanges();
var newlyInsertedElement =
DOM.nextSibling(tc.debugElement.nativeElement);
expect(newlyInsertedElement).toHaveText('dynamic(hello)');
async.done();
});
});
}));
inject([DynamicComponentLoader, TestComponentBuilder, AsyncTestCompleter],
(loader: DynamicComponentLoader, tcb: TestComponentBuilder, async) => {
tcb.overrideView(MyComp, new ViewMetadata({template: '', directives: [Location]}))
.createAsync(MyComp)
.then((tc) => {
loader.loadNextToLocation(DynamicallyLoadedWithNgContent, tc.elementRef,
null, [[DOM.createTextNode('hello')]])
.then(ref => {
tc.detectChanges();
var newlyInsertedElement =
DOM.nextSibling(tc.debugElement.nativeElement);
expect(newlyInsertedElement).toHaveText('dynamic(hello)');
async.done();
});
});
}));
});
describe('loadAsRoot', () => {
it('should allow to create, update and destroy components',
inject(
[AsyncTestCompleter, DynamicComponentLoader, DOCUMENT, Injector],
(async: AsyncTestCompleter, loader: DynamicComponentLoader, doc,
injector: Injector) => {
var rootEl = createRootElement(doc, 'child-cmp');
DOM.appendChild(doc.body, rootEl);
loader.loadAsRoot(ChildComp, null, injector).then((componentRef) => {
var el = new ComponentFixture_(componentRef);
inject([AsyncTestCompleter, DynamicComponentLoader, DOCUMENT, Injector],
(async: AsyncTestCompleter, loader: DynamicComponentLoader, doc,
injector: Injector) => {
var rootEl = createRootElement(doc, 'child-cmp');
DOM.appendChild(doc.body, rootEl);
loader.loadAsRoot(ChildComp, null, injector)
.then((componentRef) => {
var el = new ComponentFixture_(componentRef);
expect(rootEl.parentNode).toBe(doc.body);
expect(rootEl.parentNode).toBe(doc.body);
el.detectChanges();
el.detectChanges();
expect(rootEl).toHaveText('hello');
expect(rootEl).toHaveText('hello');
componentRef.instance.ctxProp = 'new';
componentRef.instance.ctxProp = 'new';
el.detectChanges();
el.detectChanges();
expect(rootEl).toHaveText('new');
expect(rootEl).toHaveText('new');
componentRef.dispose();
componentRef.dispose();
expect(rootEl.parentNode).toBeFalsy();
expect(rootEl.parentNode).toBeFalsy();
async.done();
});
}));
async.done();
});
}));
it('should allow to pass projectable nodes',
inject(
[AsyncTestCompleter, DynamicComponentLoader, DOCUMENT, Injector],
(async: AsyncTestCompleter, loader: DynamicComponentLoader, doc,
injector: Injector) => {
var rootEl = createRootElement(doc, 'dummy');
DOM.appendChild(doc.body, rootEl);
loader
.loadAsRoot(
DynamicallyLoadedWithNgContent, null, injector, null,
[[DOM.createTextNode('hello')]])
.then((_) => {
expect(rootEl).toHaveText('dynamic(hello)');
inject([AsyncTestCompleter, DynamicComponentLoader, DOCUMENT, Injector],
(async: AsyncTestCompleter, loader: DynamicComponentLoader, doc,
injector: Injector) => {
var rootEl = createRootElement(doc, 'dummy');
DOM.appendChild(doc.body, rootEl);
loader.loadAsRoot(DynamicallyLoadedWithNgContent, null, injector, null,
[[DOM.createTextNode('hello')]])
.then((_) => {
expect(rootEl).toHaveText('dynamic(hello)');
async.done();
});
}));
async.done();
});
}));
});
@@ -372,7 +381,7 @@ class DynamicallyCreatedComponentService {}
@Component({
selector: 'hello-cmp',
viewProviders: [DynamicallyCreatedComponentService],
template: '{{greeting}}'
template: "{{greeting}}"
})
class DynamicallyCreatedCmp implements OnDestroy {
greeting: string;
@@ -380,41 +389,41 @@ class DynamicallyCreatedCmp implements OnDestroy {
destroyed: boolean = false;
constructor(a: DynamicallyCreatedComponentService) {
this.greeting = 'hello';
this.greeting = "hello";
this.dynamicallyCreatedComponentService = a;
}
ngOnDestroy() { this.destroyed = true; }
}
@Component({selector: 'dummy', template: 'DynamicallyLoaded;'})
@Component({selector: 'dummy', template: "DynamicallyLoaded;"})
class DynamicallyLoaded {
}
@Component({selector: 'dummy', template: 'DynamicallyLoaded;'})
@Component({selector: 'dummy', template: "DynamicallyLoaded;"})
class DynamicallyLoadedThrows {
constructor() { throw new BaseException('ThrownInConstructor'); }
constructor() { throw new BaseException("ThrownInConstructor"); }
}
@Component({selector: 'dummy', template: 'DynamicallyLoaded2;'})
@Component({selector: 'dummy', template: "DynamicallyLoaded2;"})
class DynamicallyLoaded2 {
}
@Component({selector: 'dummy', host: {'[id]': 'id'}, template: 'DynamicallyLoadedWithHostProps;'})
@Component({selector: 'dummy', host: {'[id]': 'id'}, template: "DynamicallyLoadedWithHostProps;"})
class DynamicallyLoadedWithHostProps {
id: string;
constructor() { this.id = 'default'; }
constructor() { this.id = "default"; }
}
@Component({selector: 'dummy', template: 'dynamic(<ng-content></ng-content>)'})
@Component({selector: 'dummy', template: "dynamic(<ng-content></ng-content>)"})
class DynamicallyLoadedWithNgContent {
id: string;
constructor() { this.id = 'default'; }
constructor() { this.id = "default"; }
}
@Component({selector: 'location', template: 'Location;'})
@Component({selector: 'location', template: "Location;"})
class Location {
elementRef: ElementRef;
@@ -48,8 +48,8 @@ import {ElementRef} from 'angular2/src/core/linker/element_ref';
import {DynamicChangeDetector, ChangeDetectorRef, Parser, Lexer} from 'angular2/src/core/change_detection/change_detection';
import {ChangeDetectorRef_} from 'angular2/src/core/change_detection/change_detector_ref';
import {QueryList} from 'angular2/src/core/linker/query_list';
import {AppView, AppProtoView} from 'angular2/src/core/linker/view';
import {ViewType} from 'angular2/src/core/linker/view_type';
import {AppView, AppProtoView} from "angular2/src/core/linker/view";
import {ViewType} from "angular2/src/core/linker/view_type";
@Directive({selector: ''})
class SimpleDirective {}
@@ -101,18 +101,18 @@ class NeedsDirectiveFromHostShadowDom {
@Directive({selector: ''})
class NeedsService {
service: any;
constructor(@Inject('service') service) { this.service = service; }
constructor(@Inject("service") service) { this.service = service; }
}
@Directive({selector: ''})
class NeedsServiceFromHost {
service: any;
constructor(@Host() @Inject('service') service) { this.service = service; }
constructor(@Host() @Inject("service") service) { this.service = service; }
}
class HasEventEmitter {
emitter;
constructor() { this.emitter = 'emitter'; }
constructor() { this.emitter = "emitter"; }
}
@Directive({selector: ''})
@@ -149,7 +149,7 @@ class NeedsViewQuery {
@Directive({selector: ''})
class NeedsQueryByVarBindings {
query: QueryList<any>;
constructor(@Query('one,two') query: QueryList<any>) { this.query = query; }
constructor(@Query("one,two") query: QueryList<any>) { this.query = query; }
}
@Directive({selector: ''})
@@ -334,11 +334,11 @@ export function main() {
}));
}
describe('ProtoAppElement', () => {
describe("ProtoAppElement", () => {
init();
describe('inline strategy', () => {
it('should allow for direct access using getProviderAtIndex', () => {
it("should allow for direct access using getProviderAtIndex", () => {
var proto = protoAppElement(0, [SimpleDirective]);
expect(proto.getProviderAtIndex(0)).toBeAnInstanceOf(DirectiveProvider);
@@ -348,7 +348,7 @@ export function main() {
});
describe('dynamic strategy', () => {
it('should allow for direct access using getProviderAtIndex', () => {
it("should allow for direct access using getProviderAtIndex", () => {
var proto = protoAppElement(0, dynamicStrategyDirectives);
expect(proto.getProviderAtIndex(0)).toBeAnInstanceOf(DirectiveProvider);
@@ -359,8 +359,8 @@ export function main() {
});
});
describe('.create', () => {
it('should collect providers from all directives', () => {
describe(".create", () => {
it("should collect providers from all directives", () => {
mockDirectiveMeta.set(SimpleDirective, new DirectiveMetadata({providers: [provide('injectable1', {useValue: 'injectable1'})]}));
mockDirectiveMeta.set(SomeOtherDirective, new DirectiveMetadata({
providers: [provide('injectable2', {useValue: 'injectable2'})]
@@ -372,21 +372,21 @@ export function main() {
expect(pel.getProviderAtIndex(0).key.token).toBe(SimpleDirective);
expect(pel.getProviderAtIndex(1).key.token).toBe(SomeOtherDirective);
expect(pel.getProviderAtIndex(2).key.token).toEqual('injectable1');
expect(pel.getProviderAtIndex(3).key.token).toEqual('injectable2');
expect(pel.getProviderAtIndex(2).key.token).toEqual("injectable1");
expect(pel.getProviderAtIndex(3).key.token).toEqual("injectable2");
});
it('should collect view providers from the component', () => {
it("should collect view providers from the component", () => {
mockDirectiveMeta.set(SimpleDirective, new ComponentMetadata({
viewProviders: [provide('injectable1', {useValue: 'injectable1'})]
}));
var pel = protoAppElement(0, [SimpleDirective]);
expect(pel.getProviderAtIndex(0).key.token).toBe(SimpleDirective);
expect(pel.getProviderAtIndex(1).key.token).toEqual('injectable1');
expect(pel.getProviderAtIndex(1).key.token).toEqual("injectable1");
});
it('should flatten nested arrays in viewProviders and providers', () => {
it("should flatten nested arrays in viewProviders and providers", () => {
mockDirectiveMeta.set(SimpleDirective, new ComponentMetadata({
viewProviders: [[[provide('view', {useValue: 'view'})]]],
providers: [[[provide('host', {useValue: 'host'})]]]
@@ -394,8 +394,8 @@ export function main() {
var pel = protoAppElement(0, [SimpleDirective]);
expect(pel.getProviderAtIndex(0).key.token).toBe(SimpleDirective);
expect(pel.getProviderAtIndex(1).key.token).toEqual('view');
expect(pel.getProviderAtIndex(2).key.token).toEqual('host');
expect(pel.getProviderAtIndex(1).key.token).toEqual("view");
expect(pel.getProviderAtIndex(2).key.token).toEqual("host");
});
it('should support an arbitrary number of providers', () => {
@@ -406,7 +406,7 @@ export function main() {
});
});
describe('AppElement', () => {
describe("AppElement", () => {
init();
[{ strategy: 'inline', directives: [] }, { strategy: 'dynamic',
@@ -415,14 +415,14 @@ export function main() {
var extraDirectives = context['directives'];
describe(`${context['strategy']} strategy`, () => {
describe('injection', () => {
it('should instantiate directives that have no dependencies', () => {
describe("injection", () => {
it("should instantiate directives that have no dependencies", () => {
var directives = ListWrapper.concat([SimpleDirective], extraDirectives);
var el = appElement(null, directives);
expect(el.get(SimpleDirective)).toBeAnInstanceOf(SimpleDirective);
});
it('should instantiate directives that depend on an arbitrary number of directives', () => {
it("should instantiate directives that depend on an arbitrary number of directives", () => {
var directives = ListWrapper.concat([SimpleDirective, NeedsDirective], extraDirectives);
var el = appElement(null, directives);
@@ -432,7 +432,7 @@ export function main() {
expect(d.dependency).toBeAnInstanceOf(SimpleDirective);
});
it('should instantiate providers that have dependencies with set visibility',
it("should instantiate providers that have dependencies with set visibility",
function() {
mockDirectiveMeta.set(SimpleDirective, new ComponentMetadata({
providers: [provide('injectable1', {useValue: 'injectable1'})]
@@ -452,7 +452,7 @@ export function main() {
expect(childInj.get('injectable2')).toEqual('injectable1-injectable2');
});
it('should instantiate providers that have dependencies', () => {
it("should instantiate providers that have dependencies", () => {
var providers = [
provide('injectable1', {useValue: 'injectable1'}),
provide('injectable2', {useFactory:
@@ -466,7 +466,7 @@ export function main() {
expect(el.get('injectable2')).toEqual('injectable1-injectable2');
});
it('should instantiate viewProviders that have dependencies', () => {
it("should instantiate viewProviders that have dependencies", () => {
var viewProviders = [
provide('injectable1', {useValue: 'injectable1'}),
provide('injectable2', {useFactory:
@@ -481,7 +481,7 @@ export function main() {
expect(el.get('injectable2')).toEqual('injectable1-injectable2');
});
it('should instantiate components that depend on viewProviders providers', () => {
it("should instantiate components that depend on viewProviders providers", () => {
mockDirectiveMeta.set(NeedsService, new ComponentMetadata({
viewProviders: [provide('service', {useValue: 'service'})]
}));
@@ -490,7 +490,7 @@ export function main() {
expect(el.get(NeedsService).service).toEqual('service');
});
it('should instantiate providers lazily', () => {
it("should instantiate providers lazily", () => {
var created = false;
mockDirectiveMeta.set(SimpleDirective, new ComponentMetadata({
providers: [provide('service', {useFactory: () => created = true})]
@@ -506,7 +506,7 @@ export function main() {
expect(created).toBe(true);
});
it('should instantiate view providers lazily', () => {
it("should instantiate view providers lazily", () => {
var created = false;
mockDirectiveMeta.set(SimpleDirective, new ComponentMetadata({
viewProviders: [provide('service', {useFactory: () => created = true})]
@@ -522,18 +522,18 @@ export function main() {
expect(created).toBe(true);
});
it('should not instantiate other directives that depend on viewProviders providers',
it("should not instantiate other directives that depend on viewProviders providers",
() => {
mockDirectiveMeta.set(SimpleDirective,
new ComponentMetadata({
viewProviders: [provide('service', {useValue: 'service'})]
viewProviders: [provide("service", {useValue: "service"})]
}));
expect(() => { appElement(null, ListWrapper.concat([SimpleDirective, NeedsService], extraDirectives)); })
.toThrowError(containsRegexp(
`No provider for service! (${stringify(NeedsService) } -> service)`));
});
it('should instantiate directives that depend on providers of other directives', () => {
it("should instantiate directives that depend on providers of other directives", () => {
mockDirectiveMeta.set(SimpleDirective, new ComponentMetadata({
providers: [provide('service', {useValue: 'hostService'})]})
);
@@ -544,7 +544,7 @@ export function main() {
expect(shadowInj.get(NeedsService).service).toEqual('hostService');
});
it('should instantiate directives that depend on view providers of a component', () => {
it("should instantiate directives that depend on view providers of a component", () => {
mockDirectiveMeta.set(SimpleDirective, new ComponentMetadata({
viewProviders: [provide('service', {useValue: 'hostService'})]})
);
@@ -555,7 +555,7 @@ export function main() {
expect(shadowInj.get(NeedsService).service).toEqual('hostService');
});
it('should instantiate directives in a root embedded view that depend on view providers of a component', () => {
it("should instantiate directives in a root embedded view that depend on view providers of a component", () => {
mockDirectiveMeta.set(SimpleDirective, new ComponentMetadata({
viewProviders: [provide('service', {useValue: 'hostService'})]})
);
@@ -570,9 +570,9 @@ export function main() {
expect(rootEmbeddedEl.get(NeedsService).service).toEqual('hostService');
});
it('should instantiate directives that depend on imperatively created injector (bootstrap)', () => {
it("should instantiate directives that depend on imperatively created injector (bootstrap)", () => {
var rootInjector = Injector.resolveAndCreate([
provide('service', {useValue: 'appService'})
provide("service", {useValue: 'appService'})
]);
var view = createView(ViewType.HOST, null, null, rootInjector);
expect(appElement(null, [NeedsService], view).get(NeedsService).service).toEqual('appService');
@@ -580,9 +580,9 @@ export function main() {
expect(() => appElement(null, [NeedsServiceFromHost], view)).toThrowError();
});
it('should instantiate directives that depend on imperatively created providers (root injector)', () => {
it("should instantiate directives that depend on imperatively created providers (root injector)", () => {
var imperativelyCreatedProviders = Injector.resolve([
provide('service', {useValue: 'appService'})
provide("service", {useValue: 'appService'})
]);
var containerAppElement = appElement(null, []);
var view = createView(ViewType.HOST, containerAppElement, imperativelyCreatedProviders, null);
@@ -590,8 +590,8 @@ export function main() {
expect(appElement(null, [NeedsServiceFromHost], view).get(NeedsServiceFromHost).service).toEqual('appService');
});
it('should not instantiate a directive in a view that has a host dependency on providers'+
' of the component', () => {
it("should not instantiate a directive in a view that has a host dependency on providers"+
" of the component", () => {
mockDirectiveMeta.set(SomeOtherDirective, new DirectiveMetadata({
providers: [provide('service', {useValue: 'hostService'})]})
);
@@ -600,11 +600,11 @@ export function main() {
ListWrapper.concat([SomeOtherDirective], extraDirectives),
ListWrapper.concat([NeedsServiceFromHost], extraDirectives)
);
}).toThrowError(new RegExp('No provider for service!'));
}).toThrowError(new RegExp("No provider for service!"));
});
it('should not instantiate a directive in a view that has a host dependency on providers'+
' of a decorator directive', () => {
it("should not instantiate a directive in a view that has a host dependency on providers"+
" of a decorator directive", () => {
mockDirectiveMeta.set(SomeOtherDirective, new DirectiveMetadata({
providers: [provide('service', {useValue: 'hostService'})]}));
expect(() => {
@@ -612,10 +612,10 @@ export function main() {
ListWrapper.concat([SimpleDirective, SomeOtherDirective], extraDirectives),
ListWrapper.concat([NeedsServiceFromHost], extraDirectives)
);
}).toThrowError(new RegExp('No provider for service!'));
}).toThrowError(new RegExp("No provider for service!"));
});
it('should get directives', () => {
it("should get directives", () => {
var child = hostShadowElement(
ListWrapper.concat([SomeOtherDirective, SimpleDirective], extraDirectives),
[NeedsDirectiveFromHostShadowDom]);
@@ -626,7 +626,7 @@ export function main() {
expect(d.dependency).toBeAnInstanceOf(SimpleDirective);
});
it('should get directives from the host', () => {
it("should get directives from the host", () => {
var child = parentChildElements(ListWrapper.concat([SimpleDirective], extraDirectives),
[NeeedsDirectiveFromHost]);
@@ -636,19 +636,19 @@ export function main() {
expect(d.dependency).toBeAnInstanceOf(SimpleDirective);
});
it('should throw when a dependency cannot be resolved', () => {
it("should throw when a dependency cannot be resolved", () => {
expect(() => appElement(null, ListWrapper.concat([NeeedsDirectiveFromHost], extraDirectives)))
.toThrowError(containsRegexp(
`No provider for ${stringify(SimpleDirective) }! (${stringify(NeeedsDirectiveFromHost) } -> ${stringify(SimpleDirective) })`));
});
it('should inject null when an optional dependency cannot be resolved', () => {
it("should inject null when an optional dependency cannot be resolved", () => {
var el = appElement(null, ListWrapper.concat([OptionallyNeedsDirective], extraDirectives));
var d = el.get(OptionallyNeedsDirective);
expect(d.dependency).toEqual(null);
});
it('should allow for direct access using getDirectiveAtIndex', () => {
it("should allow for direct access using getDirectiveAtIndex", () => {
var providers =
ListWrapper.concat([SimpleDirective], extraDirectives);
@@ -662,7 +662,7 @@ export function main() {
.toThrowError(`Index ${firsIndexOut} is out-of-bounds.`);
});
it('should instantiate directives that depend on the containing component', () => {
it("should instantiate directives that depend on the containing component", () => {
mockDirectiveMeta.set(SimpleDirective, new ComponentMetadata());
var shadow = hostShadowElement(ListWrapper.concat([SimpleDirective], extraDirectives),
[NeeedsDirectiveFromHost]);
@@ -672,7 +672,7 @@ export function main() {
expect(d.dependency).toBeAnInstanceOf(SimpleDirective);
});
it('should not instantiate directives that depend on other directives in the containing component\'s ElementInjector',
it("should not instantiate directives that depend on other directives in the containing component's ElementInjector",
() => {
mockDirectiveMeta.set(SomeOtherDirective, new ComponentMetadata());
expect(() =>
@@ -708,13 +708,13 @@ export function main() {
});
});
describe('refs', () => {
it('should inject ElementRef', () => {
describe("refs", () => {
it("should inject ElementRef", () => {
var el = appElement(null, ListWrapper.concat([NeedsElementRef], extraDirectives));
expect(el.get(NeedsElementRef).elementRef).toBe(el.ref);
});
it('should inject ChangeDetectorRef of the component\'s view into the component via a proxy', () => {
it("should inject ChangeDetectorRef of the component's view into the component via a proxy", () => {
mockDirectiveMeta.set(ComponentNeedsChangeDetectorRef, new ComponentMetadata());
var host = appElement(null, ListWrapper.concat([ComponentNeedsChangeDetectorRef], extraDirectives));
var view = createView(ViewType.COMPONENT, host);
@@ -723,7 +723,7 @@ export function main() {
expect((<any>view.changeDetector).spy('markPathToRootAsCheckOnce')).toHaveBeenCalled();
});
it('should inject ChangeDetectorRef of the containing component into directives', () => {
it("should inject ChangeDetectorRef of the containing component into directives", () => {
mockDirectiveMeta.set(DirectiveNeedsChangeDetectorRef, new DirectiveMetadata());
var view = createView(ViewType.HOST);
var el = appElement(null, ListWrapper.concat([DirectiveNeedsChangeDetectorRef], extraDirectives), view);
@@ -735,12 +735,12 @@ export function main() {
expect(el.get(NeedsViewContainer).viewContainer).toBeAnInstanceOf(ViewContainerRef_);
});
it('should inject TemplateRef', () => {
it("should inject TemplateRef", () => {
var el = appElement(null, ListWrapper.concat([NeedsTemplateRef], extraDirectives), null, dummyViewFactory);
expect(el.get(NeedsTemplateRef).templateRef.elementRef).toBe(el.ref);
});
it('should throw if there is no TemplateRef', () => {
it("should throw if there is no TemplateRef", () => {
expect(() => appElement(null, ListWrapper.concat([NeedsTemplateRef], extraDirectives)))
.toThrowError(
`No provider for TemplateRef! (${stringify(NeedsTemplateRef) } -> TemplateRef)`);
@@ -795,7 +795,7 @@ export function main() {
var dirs:Type[] = [NeedsQueryByVarBindings];
var dirVariableBindings:{[key:string]:number} = {
'one': null // element
"one": null // element
};
var el = appElement(null, dirs.concat(extraDirectives), null, null, null, dirVariableBindings);
@@ -810,8 +810,8 @@ export function main() {
var dirs:Type[] = [NeedsQueryByVarBindings, NeedsDirective, SimpleDirective];
var dirVariableBindings:{[key:string]:number} = {
'one': 2, // 2 is the index of SimpleDirective
'two': 1 // 1 is the index of NeedsDirective
"one": 2, // 2 is the index of SimpleDirective
"two": 1 // 1 is the index of NeedsDirective
};
var el = appElement(null, dirs.concat(extraDirectives), null, null, null, dirVariableBindings);
File diff suppressed because it is too large Load Diff
@@ -1,9 +1,42 @@
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, el, dispatchEvent, expect, iit, inject, beforeEachProviders, it, xit, containsRegexp, stringifyElement, TestComponentBuilder, ComponentFixture, fakeAsync, tick} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
xdescribe,
describe,
el,
dispatchEvent,
expect,
iit,
inject,
beforeEachProviders,
it,
xit,
containsRegexp,
stringifyElement,
TestComponentBuilder,
ComponentFixture,
fakeAsync,
tick
} from 'angular2/testing_internal';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {bind, provide, forwardRef, Component, Directive, ElementRef, TemplateRef, ViewContainerRef, ViewEncapsulation, ViewMetadata} from 'angular2/core';
import {By,} from 'angular2/platform/common_dom';
import {
bind,
provide,
forwardRef,
Component,
Directive,
ElementRef,
TemplateRef,
ViewContainerRef,
ViewEncapsulation,
ViewMetadata
} from 'angular2/core';
import {
By,
} from 'angular2/platform/common_dom';
import {getAllDebugNodes} from 'angular2/src/core/debug/debug_node';
export function main() {
@@ -12,8 +45,8 @@ export function main() {
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<simple>' +
'<div>A</div>' +
'</simple>',
'<div>A</div>' +
'</simple>',
directives: [Simple]
}))
.createAsync(MainComp)
@@ -27,8 +60,8 @@ export function main() {
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '{{\'START(\'}}<simple>' +
'{{text}}' +
'</simple>{{\')END\'}}',
'{{text}}' +
'</simple>{{\')END\'}}',
directives: [Simple]
}))
.createAsync(MainComp)
@@ -104,8 +137,8 @@ export function main() {
it('should not show the light dom even if there is no content tag',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(
MainComp, new ViewMetadata({template: '<empty>A</empty>', directives: [Empty]}))
tcb.overrideView(MainComp,
new ViewMetadata({template: '<empty>A</empty>', directives: [Empty]}))
.createAsync(MainComp)
.then((main) => {
@@ -118,10 +151,10 @@ export function main() {
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<multiple-content-tags>' +
'<div>B</div>' +
'<div>C</div>' +
'<div class="left">A</div>' +
'</multiple-content-tags>',
'<div>B</div>' +
'<div>C</div>' +
'<div class="left">A</div>' +
'</multiple-content-tags>',
directives: [MultipleContentTagsComponent]
}))
.createAsync(MainComp)
@@ -136,9 +169,9 @@ export function main() {
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<multiple-content-tags>' +
'<div>B<div class="left">A</div></div>' +
'<div>C</div>' +
'</multiple-content-tags>',
'<div>B<div class="left">A</div></div>' +
'<div>C</div>' +
'</multiple-content-tags>',
directives: [MultipleContentTagsComponent]
}))
.createAsync(MainComp)
@@ -149,13 +182,13 @@ export function main() {
});
}));
it('should redistribute direct child viewcontainers when the light dom changes',
it("should redistribute direct child viewcontainers when the light dom changes",
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<multiple-content-tags>' +
'<template manual class="left"><div>A1</div></template>' +
'<div>B</div>' +
'</multiple-content-tags>',
'<template manual class="left"><div>A1</div></template>' +
'<div>B</div>' +
'</multiple-content-tags>',
directives: [MultipleContentTagsComponent, ManualViewportDirective]
}))
.createAsync(MainComp)
@@ -177,13 +210,13 @@ export function main() {
});
}));
it('should support nested components',
it("should support nested components",
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<outer-with-indirect-nested>' +
'<div>A</div>' +
'<div>B</div>' +
'</outer-with-indirect-nested>',
'<div>A</div>' +
'<div>B</div>' +
'</outer-with-indirect-nested>',
directives: [OuterWithIndirectNestedComponent]
}))
.createAsync(MainComp)
@@ -194,14 +227,14 @@ export function main() {
});
}));
it('should support nesting with content being direct child of a nested component',
it("should support nesting with content being direct child of a nested component",
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<outer>' +
'<template manual class="left"><div>A</div></template>' +
'<div>B</div>' +
'<div>C</div>' +
'</outer>',
'<template manual class="left"><div>A</div></template>' +
'<div>B</div>' +
'<div>C</div>' +
'</outer>',
directives: [OuterComponent, ManualViewportDirective],
}))
.createAsync(MainComp)
@@ -223,10 +256,10 @@ export function main() {
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<conditional-content>' +
'<div class="left">A</div>' +
'<div>B</div>' +
'<div>C</div>' +
'</conditional-content>',
'<div class="left">A</div>' +
'<div>B</div>' +
'<div>C</div>' +
'</conditional-content>',
directives: [ConditionalContentComponent]
}))
.createAsync(MainComp)
@@ -293,9 +326,9 @@ export function main() {
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<empty>' +
' <template manual><div>A</div></template>' +
'</empty>' +
'START(<div project></div>)END',
' <template manual><div>A</div></template>' +
'</empty>' +
'START(<div project></div>)END',
directives: [Empty, ProjectDirective, ManualViewportDirective],
}))
.createAsync(MainComp)
@@ -326,7 +359,7 @@ export function main() {
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<simple><template manual><div>A</div></template></simple>' +
'START(<div project></div>)END',
'START(<div project></div>)END',
directives: [Simple, ProjectDirective, ManualViewportDirective],
}))
.createAsync(MainComp)
@@ -351,10 +384,10 @@ export function main() {
tcb.overrideView(
MainComp, new ViewMetadata({
template: '<conditional-content>' +
'<div class="left">A</div>' +
'<div>B</div>' +
'</conditional-content>' +
'START(<div project></div>)END',
'<div class="left">A</div>' +
'<div>B</div>' +
'</conditional-content>' +
'START(<div project></div>)END',
directives:
[ConditionalContentComponent, ProjectDirective, ManualViewportDirective]
}))
@@ -386,8 +419,8 @@ export function main() {
// the presence of ng-content elements!
it('should still allow to implement a recursive trees',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(
MainComp, new ViewMetadata({template: '<tree></tree>', directives: [Tree]}))
tcb.overrideView(MainComp,
new ViewMetadata({template: '<tree></tree>', directives: [Tree]}))
.createAsync(MainComp)
.then((main) => {
@@ -408,7 +441,7 @@ export function main() {
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<simple-native1><div>A</div></simple-native1>' +
'<simple-native2><div>B</div></simple-native2>',
'<simple-native2><div>B</div></simple-native2>',
directives: [SimpleNative1, SimpleNative2]
}))
.createAsync(MainComp)
@@ -477,9 +510,8 @@ export function main() {
.then((main) => {
main.detectChanges();
expect(DOM.getInnerHTML(main.debugElement.nativeElement))
.toEqual(
'<cmp-a><cmp-b><cmp-d><d>cmp-d</d></cmp-d></cmp-b>' +
'<cmp-c><c>cmp-c</c></cmp-c></cmp-a>');
.toEqual('<cmp-a><cmp-b><cmp-d><d>cmp-d</d></cmp-d></cmp-b>' +
'<cmp-c><c>cmp-c</c></cmp-c></cmp-a>');
async.done();
});
}));
@@ -494,9 +526,8 @@ export function main() {
.then((main) => {
main.detectChanges();
expect(DOM.getInnerHTML(main.debugElement.nativeElement))
.toEqual(
'<cmp-a1>a1<cmp-b11>b11</cmp-b11><cmp-b12>b12</cmp-b12></cmp-a1>' +
'<cmp-a2>a2<cmp-b21>b21</cmp-b21><cmp-b22>b22</cmp-b22></cmp-a2>');
.toEqual('<cmp-a1>a1<cmp-b11>b11</cmp-b11><cmp-b12>b12</cmp-b12></cmp-a1>' +
'<cmp-a2>a2<cmp-b21>b21</cmp-b21><cmp-b22>b22</cmp-b22></cmp-a2>');
async.done();
});
}));
@@ -505,11 +536,11 @@ export function main() {
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(MainComp, new ViewMetadata({
template: '<conditional-content>' +
'<div class="left">A</div>' +
'<template manual class="left">B</template>' +
'<div class="left">C</div>' +
'<div>D</div>' +
'</conditional-content>',
'<div class="left">A</div>' +
'<template manual class="left">B</template>' +
'<div class="left">C</div>' +
'<div>D</div>' +
'</conditional-content>',
directives: [ConditionalContentComponent, ManualViewportDirective]
}))
.createAsync(MainComp)
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,15 @@
import {describe, it, expect, beforeEach, ddescribe, iit, xit, el, fakeAsync, tick} from 'angular2/testing_internal';
import {
describe,
it,
expect,
beforeEach,
ddescribe,
iit,
xit,
el,
fakeAsync,
tick
} from 'angular2/testing_internal';
import {MapWrapper, ListWrapper, iterateListLike} from 'angular2/src/facade/collection';
import {IS_DART, StringWrapper} from 'angular2/src/facade/lang';
import {ObservableWrapper} from 'angular2/src/facade/async';
@@ -49,22 +60,22 @@ export function main() {
if (!IS_DART) {
it('should support filter', () => {
queryList.reset(['one', 'two']);
expect((<_JsQueryList>queryList).filter((x) => x == 'one')).toEqual(['one']);
expect((<_JsQueryList>queryList).filter((x) => x == "one")).toEqual(['one']);
});
it('should support reduce', () => {
queryList.reset(['one', 'two']);
expect((<_JsQueryList>queryList).reduce((a, x) => a + x, 'start:')).toEqual('start:onetwo');
queryList.reset(["one", "two"]);
expect((<_JsQueryList>queryList).reduce((a, x) => a + x, "start:")).toEqual("start:onetwo");
});
it('should support toArray', () => {
queryList.reset(['one', 'two']);
expect((<_JsQueryList>queryList).reduce((a, x) => a + x, 'start:')).toEqual('start:onetwo');
queryList.reset(["one", "two"]);
expect((<_JsQueryList>queryList).reduce((a, x) => a + x, "start:")).toEqual("start:onetwo");
});
it('should support toArray', () => {
queryList.reset(['one', 'two']);
expect((<_JsQueryList>queryList).toArray()).toEqual(['one', 'two']);
queryList.reset(["one", "two"]);
expect((<_JsQueryList>queryList).toArray()).toEqual(["one", "two"]);
});
}
@@ -102,7 +113,7 @@ export function main() {
var recorded;
ObservableWrapper.subscribe(queryList.changes, (v: any) => { recorded = v; });
queryList.reset(['one']);
queryList.reset(["one"]);
queryList.notifyOnChanges();
tick();
@@ -7,29 +7,29 @@ class SomePipe {}
@Component({
selector: 'sample',
template: 'some template',
template: "some template",
directives: [SomeDir],
pipes: [SomePipe],
styles: ['some styles']
styles: ["some styles"]
})
class ComponentWithView {
}
@Component({
selector: 'sample',
template: 'some template',
template: "some template",
directives: [SomeDir],
pipes: [SomePipe],
styles: ['some styles']
styles: ["some styles"]
})
class ComponentWithTemplate {
}
@Component({selector: 'sample', template: 'some template'})
@Component({selector: 'sample', template: "some template"})
class ComponentWithViewTemplate {
}
@Component({selector: 'sample', templateUrl: 'some template url', template: 'some template'})
@Component({selector: 'sample', templateUrl: "some template url", template: "some template"})
class ComponentWithViewTemplateUrl {
}
@@ -41,30 +41,31 @@ class ComponentWithoutView {
class SimpleClass {}
export function main() {
describe('ViewResolver', () => {
describe("ViewResolver", () => {
var resolver: ViewResolver;
beforeEach(() => { resolver = new ViewResolver(); });
it('should read out the View metadata from the Component metadata', () => {
var viewMetadata = resolver.resolve(ComponentWithTemplate);
expect(viewMetadata).toEqual(new ViewMetadata({
template: 'some template',
directives: [SomeDir],
pipes: [SomePipe],
styles: ['some styles']
}));
expect(viewMetadata)
.toEqual(new ViewMetadata({
template: "some template",
directives: [SomeDir],
pipes: [SomePipe],
styles: ["some styles"]
}));
});
it('should throw when Component has no View decorator and no template is set', () => {
expect(() => resolver.resolve(ComponentWithoutView))
.toThrowErrorWith(
'Component \'ComponentWithoutView\' must have either \'template\' or \'templateUrl\' set');
"Component 'ComponentWithoutView' must have either 'template' or 'templateUrl' set");
});
it('should throw when simple class has no View decorator and no template is set', () => {
expect(() => resolver.resolve(SimpleClass))
.toThrowErrorWith('Could not compile \'SimpleClass\' because it is not a component.');
.toThrowErrorWith("Could not compile 'SimpleClass' because it is not a component.");
});
});
}
@@ -1,4 +1,14 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, expect, iit, inject, it, xit,} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/testing_internal';
import {Component, Directive} from 'angular2/core';
import {reflector} from 'angular2/src/core/reflection/reflection';
@@ -1,4 +1,8 @@
import {makeDecorator, makeParamDecorator, makePropDecorator} from 'angular2/src/core/util/decorators';
import {
makeDecorator,
makeParamDecorator,
makePropDecorator
} from 'angular2/src/core/util/decorators';
export class ClassDecoratorMeta {
constructor(public value) {}
@@ -1,8 +1,24 @@
import {describe, it, iit, ddescribe, expect, beforeEach, browserDetection} from 'angular2/testing_internal';
import {
describe,
it,
iit,
ddescribe,
expect,
beforeEach,
browserDetection
} from 'angular2/testing_internal';
import {OnInit} from 'angular2/core';
import {Reflector, ReflectionInfo} from 'angular2/src/core/reflection/reflection';
import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities';
import {ClassDecorator, ParamDecorator, PropDecorator, classDecorator, paramDecorator, propDecorator, HasGetterAndSetterDecorators} from './reflector_common';
import {
ClassDecorator,
ParamDecorator,
PropDecorator,
classDecorator,
paramDecorator,
propDecorator,
HasGetterAndSetterDecorators
} from './reflector_common';
import {IS_DART} from 'angular2/src/facade/lang';
class AType {
@@ -13,13 +29,14 @@ class AType {
@ClassDecorator('class')
class ClassWithDecorators {
@PropDecorator('p1') @PropDecorator('p2') a;
@PropDecorator("p1") @PropDecorator("p2") a;
b;
@PropDecorator('p3')
set c(value) {}
@PropDecorator("p3")
set c(value) {
}
constructor(@ParamDecorator('a') a: AType, @ParamDecorator('b') b: AType) {
constructor(@ParamDecorator("a") a: AType, @ParamDecorator("b") b: AType) {
this.a = a;
this.b = b;
}
@@ -68,19 +85,19 @@ export function main() {
beforeEach(() => { reflector = new Reflector(new ReflectionCapabilities()); });
describe('usage tracking', () => {
describe("usage tracking", () => {
beforeEach(() => { reflector = new Reflector(null); });
it('should be disabled by default', () => {
it("should be disabled by default", () => {
expect(() => reflector.listUnusedKeys()).toThrowError('Usage tracking is disabled');
});
it('should report unused keys', () => {
it("should report unused keys", () => {
reflector.trackUsage();
expect(reflector.listUnusedKeys()).toEqual([]);
reflector.registerType(AType, new ReflectionInfo(null, null, () => 'AType'));
reflector.registerType(TestObj, new ReflectionInfo(null, null, () => 'TestObj'));
reflector.registerType(AType, new ReflectionInfo(null, null, () => "AType"));
reflector.registerType(TestObj, new ReflectionInfo(null, null, () => "TestObj"));
expect(reflector.listUnusedKeys()).toEqual([AType, TestObj]);
reflector.factory(AType);
@@ -91,8 +108,8 @@ export function main() {
});
});
describe('factory', () => {
it('should create a factory for the given type', () => {
describe("factory", () => {
it("should create a factory for the given type", () => {
var obj = reflector.factory(TestObj)(1, 2);
expect(obj.a).toEqual(1);
@@ -102,7 +119,7 @@ export function main() {
// Makes Edge to disconnect when running the full unit test campaign
// TODO: remove when issue is solved: https://github.com/angular/angular/issues/4756
if (!browserDetection.isEdge) {
it('should check args from no to max', () => {
it("should check args from no to max", () => {
var f = t => reflector.factory(t);
var checkArgs = (obj, args) => expect(obj.args).toEqual(args);
@@ -132,141 +149,141 @@ export function main() {
});
}
it('should throw when more than 20 arguments',
it("should throw when more than 20 arguments",
() => { expect(() => reflector.factory(TestObjWith21Args)).toThrowError(); });
it('should return a registered factory if available', () => {
reflector.registerType(TestObj, new ReflectionInfo(null, null, () => 'fake'));
expect(reflector.factory(TestObj)()).toEqual('fake');
it("should return a registered factory if available", () => {
reflector.registerType(TestObj, new ReflectionInfo(null, null, () => "fake"));
expect(reflector.factory(TestObj)()).toEqual("fake");
});
});
describe('parameters', () => {
it('should return an array of parameters for a type', () => {
describe("parameters", () => {
it("should return an array of parameters for a type", () => {
var p = reflector.parameters(ClassWithDecorators);
expect(p).toEqual([[AType, paramDecorator('a')], [AType, paramDecorator('b')]]);
});
it('should work for a class without annotations', () => {
it("should work for a class without annotations", () => {
var p = reflector.parameters(ClassWithoutDecorators);
expect(p.length).toEqual(2);
});
it('should return registered parameters if available', () => {
it("should return registered parameters if available", () => {
reflector.registerType(TestObj, new ReflectionInfo(null, [[1], [2]]));
expect(reflector.parameters(TestObj)).toEqual([[1], [2]]);
});
it('should return an empty list when no parameters field in the stored type info', () => {
it("should return an empty list when no parameters field in the stored type info", () => {
reflector.registerType(TestObj, new ReflectionInfo());
expect(reflector.parameters(TestObj)).toEqual([]);
});
});
describe('propMetadata', () => {
it('should return a string map of prop metadata for the given class', () => {
describe("propMetadata", () => {
it("should return a string map of prop metadata for the given class", () => {
var p = reflector.propMetadata(ClassWithDecorators);
expect(p['a']).toEqual([propDecorator('p1'), propDecorator('p2')]);
expect(p['c']).toEqual([propDecorator('p3')]);
expect(p["a"]).toEqual([propDecorator("p1"), propDecorator("p2")]);
expect(p["c"]).toEqual([propDecorator("p3")]);
});
it('should return registered meta if available', () => {
reflector.registerType(TestObj, new ReflectionInfo(null, null, null, null, {'a': [1, 2]}));
expect(reflector.propMetadata(TestObj)).toEqual({'a': [1, 2]});
it("should return registered meta if available", () => {
reflector.registerType(TestObj, new ReflectionInfo(null, null, null, null, {"a": [1, 2]}));
expect(reflector.propMetadata(TestObj)).toEqual({"a": [1, 2]});
});
if (IS_DART) {
it('should merge metadata from getters and setters', () => {
it("should merge metadata from getters and setters", () => {
var p = reflector.propMetadata(HasGetterAndSetterDecorators);
expect(p['a']).toEqual([propDecorator('get'), propDecorator('set')]);
expect(p["a"]).toEqual([propDecorator("get"), propDecorator("set")]);
});
}
});
describe('annotations', () => {
it('should return an array of annotations for a type', () => {
describe("annotations", () => {
it("should return an array of annotations for a type", () => {
var p = reflector.annotations(ClassWithDecorators);
expect(p).toEqual([classDecorator('class')]);
});
it('should return registered annotations if available', () => {
it("should return registered annotations if available", () => {
reflector.registerType(TestObj, new ReflectionInfo([1, 2]));
expect(reflector.annotations(TestObj)).toEqual([1, 2]);
});
it('should work for a class without annotations', () => {
it("should work for a class without annotations", () => {
var p = reflector.annotations(ClassWithoutDecorators);
expect(p).toEqual([]);
});
});
if (IS_DART) {
describe('interfaces', () => {
it('should return an array of interfaces for a type', () => {
describe("interfaces", () => {
it("should return an array of interfaces for a type", () => {
var p = reflector.interfaces(ClassImplementingInterface);
expect(p).toEqual([Interface, Interface2]);
});
it('should return an empty array otherwise', () => {
it("should return an empty array otherwise", () => {
var p = reflector.interfaces(ClassWithDecorators);
expect(p).toEqual([]);
});
it('should throw for undeclared lifecycle interfaces',
it("should throw for undeclared lifecycle interfaces",
() => { expect(() => reflector.interfaces(ClassDoesNotDeclareOnInit)).toThrowError(); });
it('should throw for class inheriting a lifecycle impl and not declaring the interface',
it("should throw for class inheriting a lifecycle impl and not declaring the interface",
() => {
expect(() => reflector.interfaces(SubClassDoesNotDeclareOnInit)).toThrowError();
});
});
}
describe('getter', () => {
it('returns a function reading a property', () => {
describe("getter", () => {
it("returns a function reading a property", () => {
var getA = reflector.getter('a');
expect(getA(new TestObj(1, 2))).toEqual(1);
});
it('should return a registered getter if available', () => {
reflector.registerGetters({'abc': (obj) => 'fake'});
expect(reflector.getter('abc')('anything')).toEqual('fake');
it("should return a registered getter if available", () => {
reflector.registerGetters({"abc": (obj) => "fake"});
expect(reflector.getter("abc")("anything")).toEqual("fake");
});
});
describe('setter', () => {
it('returns a function setting a property', () => {
describe("setter", () => {
it("returns a function setting a property", () => {
var setA = reflector.setter('a');
var obj = new TestObj(1, 2);
setA(obj, 100);
expect(obj.a).toEqual(100);
});
it('should return a registered setter if available', () => {
it("should return a registered setter if available", () => {
var updateMe;
reflector.registerSetters({'abc': (obj, value) => { updateMe = value; }});
reflector.setter('abc')('anything', 'fake');
reflector.registerSetters({"abc": (obj, value) => { updateMe = value; }});
reflector.setter("abc")("anything", "fake");
expect(updateMe).toEqual('fake');
expect(updateMe).toEqual("fake");
});
});
describe('method', () => {
it('returns a function invoking a method', () => {
describe("method", () => {
it("returns a function invoking a method", () => {
var func = reflector.method('identity');
var obj = new TestObj(1, 2);
expect(func(obj, ['value'])).toEqual('value');
});
it('should return a registered method if available', () => {
reflector.registerMethods({'abc': (obj, args) => args});
expect(reflector.method('abc')('anything', ['fake'])).toEqual(['fake']);
it("should return a registered method if available", () => {
reflector.registerMethods({"abc": (obj, args) => args});
expect(reflector.method("abc")("anything", ["fake"])).toEqual(['fake']);
});
});
if (IS_DART) {
describe('importUri', () => {
it('should return the importUri for a type', () => {
describe("importUri", () => {
it("should return the importUri for a type", () => {
expect(reflector.importUri(TestObjWith00Args)
.endsWith('test/core/reflection/reflector_spec.dart'))
.toBe(true);
@@ -337,89 +354,82 @@ class TestObjWith09Args {
class TestObjWith10Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any) {
this.args = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
}
}
class TestObjWith11Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any) {
this.args = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11];
}
}
class TestObjWith12Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any, a12: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any, a12: any) {
this.args = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12];
}
}
class TestObjWith13Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any, a12: any, a13: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any, a12: any, a13: any) {
this.args = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13];
}
}
class TestObjWith14Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any, a12: any, a13: any, a14: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any, a12: any, a13: any, a14: any) {
this.args = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14];
}
}
class TestObjWith15Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any, a12: any, a13: any, a14: any, a15: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any, a12: any, a13: any, a14: any, a15: any) {
this.args = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15];
}
}
class TestObjWith16Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any, a12: any, a13: any, a14: any, a15: any, a16: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any, a12: any, a13: any, a14: any, a15: any, a16: any) {
this.args = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16];
}
}
class TestObjWith17Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any, a12: any, a13: any, a14: any, a15: any, a16: any, a17: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any, a12: any, a13: any, a14: any, a15: any, a16: any, a17: any) {
this.args = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17];
}
}
class TestObjWith18Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any, a12: any, a13: any, a14: any, a15: any, a16: any, a17: any, a18: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any, a12: any, a13: any, a14: any, a15: any, a16: any, a17: any,
a18: any) {
this.args = [a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18];
}
}
class TestObjWith19Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any, a12: any, a13: any, a14: any, a15: any, a16: any, a17: any, a18: any, a19: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any, a12: any, a13: any, a14: any, a15: any, a16: any, a17: any,
a18: any, a19: any) {
this.args =
[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19];
}
@@ -427,10 +437,9 @@ class TestObjWith19Args {
class TestObjWith20Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any, a12: any, a13: any, a14: any, a15: any, a16: any, a17: any, a18: any, a19: any,
a20: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any, a12: any, a13: any, a14: any, a15: any, a16: any, a17: any,
a18: any, a19: any, a20: any) {
this.args =
[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20];
}
@@ -438,13 +447,31 @@ class TestObjWith20Args {
class TestObjWith21Args {
args: any[];
constructor(
a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any, a10: any,
a11: any, a12: any, a13: any, a14: any, a15: any, a16: any, a17: any, a18: any, a19: any,
a20: any, a21: any) {
constructor(a1: any, a2: any, a3: any, a4: any, a5: any, a6: any, a7: any, a8: any, a9: any,
a10: any, a11: any, a12: any, a13: any, a14: any, a15: any, a16: any, a17: any,
a18: any, a19: any, a20: any, a21: any) {
this.args = [
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14, a15, a16, a17, a18, a19, a20, a21
a1,
a2,
a3,
a4,
a5,
a6,
a7,
a8,
a9,
a10,
a11,
a12,
a13,
a14,
a15,
a16,
a17,
a18,
a19,
a20,
a21
];
}
}
+6 -1
View File
@@ -1,4 +1,9 @@
import {ChangeDetector, ChangeDetectorRef, ProtoChangeDetector, DynamicChangeDetector} from 'angular2/src/core/change_detection/change_detection';
import {
ChangeDetector,
ChangeDetectorRef,
ProtoChangeDetector,
DynamicChangeDetector
} from 'angular2/src/core/change_detection/change_detection';
import {Renderer} from 'angular2/src/core/render/api';
import {DirectiveResolver} from 'angular2/src/core/linker/directive_resolver';
@@ -1,5 +1,17 @@
import {Injectable} from 'angular2/src/core/di';
import {AsyncTestCompleter, inject, describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach, SpyObject} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
inject,
describe,
ddescribe,
it,
iit,
xit,
xdescribe,
expect,
beforeEach,
SpyObject
} from 'angular2/testing_internal';
import {Testability} from 'angular2/src/core/testability/testability';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {normalizeBlank, scheduleMicroTask} from 'angular2/src/facade/lang';
@@ -1,4 +1,14 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, expect, iit, inject, it, xit,} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
} from 'angular2/testing_internal';
import {makeDecorator, makeParamDecorator, Class} from 'angular2/src/core/util/decorators';
import {global} from 'angular2/src/facade/lang';
@@ -57,16 +67,19 @@ export function main() {
describe('Class', () => {
it('should create a class', () => {
var i0, i1;
var MyClass = (<any>TestDecorator('test-works')).Class(<any>{
extends: Class(<any>{
constructor: function() {},
extendWorks: function() { return 'extend ' + this.arg; }
}),
constructor: [String, function(arg) { this.arg = arg; }],
methodA: [i0 = new Inject(String), [i1 = Inject(String), Number], function(a, b) {}],
works: function() { return this.arg; },
prototype: 'IGNORE'
});
var MyClass =
(<any>TestDecorator('test-works'))
.Class(<any>{
extends: Class(<any>{
constructor: function() {},
extendWorks: function() { return 'extend ' + this.arg; }
}),
constructor: [String, function(arg) { this.arg = arg; }],
methodA:
[i0 = new Inject(String), [i1 = Inject(String), Number], function(a, b) {}],
works: function() { return this.arg; },
prototype: 'IGNORE'
});
var obj: any = new MyClass('WORKS');
expect(obj.arg).toEqual('WORKS');
expect(obj.works()).toEqual('WORKS');
@@ -85,39 +98,38 @@ export function main() {
it('should ensure that last constructor is required', () => {
expect(() => { (<Function>Class)({}); })
.toThrowError(
'Only Function or Array is supported in Class definition for key \'constructor\' is \'undefined\'');
"Only Function or Array is supported in Class definition for key 'constructor' is 'undefined'");
});
it('should ensure that we dont accidently patch native objects', () => {
expect(() => {
(<Function>Class)({constructor: Object});
}).toThrowError('Can not use native Object as constructor');
expect(() => { (<Function>Class)({constructor: Object}); })
.toThrowError("Can not use native Object as constructor");
});
it('should ensure that last position is function', () => {
expect(() => {Class({constructor: []})})
.toThrowError(
'Last position of Class method array must be Function in key constructor was \'undefined\'');
"Last position of Class method array must be Function in key constructor was 'undefined'");
});
it('should ensure that annotation count matches parameters count', () => {
expect(() => {Class({constructor: [String, function MyType() {}]})})
.toThrowError(
'Number of annotations (1) does not match number of arguments (0) in the function: MyType');
"Number of annotations (1) does not match number of arguments (0) in the function: MyType");
});
it('should ensure that only Function|Arrays are supported', () => {
expect(() => { Class(<any>{constructor: function() {}, method: 'non_function'}); })
.toThrowError(
'Only Function or Array is supported in Class definition for key \'method\' is \'non_function\'');
"Only Function or Array is supported in Class definition for key 'method' is 'non_function'");
});
it('should ensure that extends is a Function', () => {
expect(() => {(<Function>Class)({extends: 'non_type', constructor: function() {}})})
.toThrowError(
'Class definition \'extends\' property must be a constructor function was: non_type');
"Class definition 'extends' property must be a constructor function was: non_type");
});
});
});
+28 -13
View File
@@ -1,6 +1,24 @@
import {AsyncTestCompleter, beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit, Log, browserDetection} from 'angular2/testing_internal';
import {
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xdescribe,
xit,
Log,
browserDetection
} from 'angular2/testing_internal';
import {PromiseCompleter, PromiseWrapper, TimerWrapper, ObservableWrapper} from 'angular2/src/facade/async';
import {
PromiseCompleter,
PromiseWrapper,
TimerWrapper,
ObservableWrapper
} from 'angular2/src/facade/async';
import {BaseException} from 'angular2/src/facade/exceptions';
import {IS_DART, scheduleMicroTask, isPresent} from 'angular2/src/facade/lang';
@@ -50,7 +68,7 @@ function runNgZoneNoLog(fn: () => any) {
}
export function main() {
describe('NgZone', () => {
describe("NgZone", () => {
function createZone(enableLongStackTrace) {
return new NgZone({enableLongStackTrace: enableLongStackTrace});
@@ -103,7 +121,7 @@ export function main() {
scheduleMicroTask(() => {
scheduleMicroTask(() => {
c.resolve(null);
throw new BaseException('ddd');
throw new BaseException("ddd");
});
});
});
@@ -228,9 +246,8 @@ function commonTests() {
macroTask(() => {
expect(_log.result())
.toEqual(
'onUnstable; run; onMicrotaskEmpty; onMicrotaskEmpty 1; ' +
'onMicrotaskEmpty; onMicrotaskEmpty 2; onStable');
.toEqual('onUnstable; run; onMicrotaskEmpty; onMicrotaskEmpty 1; ' +
'onMicrotaskEmpty; onMicrotaskEmpty 2; onStable');
async.done();
}, resultTimer);
}), testTimeout);
@@ -297,9 +314,8 @@ function commonTests() {
macroTask(() => {
expect(_log.result())
.toEqual(
'onUnstable; run; onMicrotaskEmpty; onMyMicrotaskEmpty; ' +
'onMicrotaskEmpty; onMyMicrotaskEmpty; onStable');
.toEqual('onUnstable; run; onMicrotaskEmpty; onMyMicrotaskEmpty; ' +
'onMicrotaskEmpty; onMyMicrotaskEmpty; onStable');
async.done();
}, resultTimer);
}), testTimeout);
@@ -661,9 +677,8 @@ function commonTests() {
macroTask(() => {
expect(_log.result())
.toEqual(
'onUnstable; zone run; onMicrotaskEmpty; onStable; ' +
'onUnstable; promise then; onMicrotaskEmpty; onStable');
.toEqual('onUnstable; zone run; onMicrotaskEmpty; onStable; ' +
'onUnstable; promise then; onMicrotaskEmpty; onStable');
async.done();
}, resultTimer);
}), testTimeout);