test: move remaining fixmeIvy to test level (#27354)

Moves all of the remaning `describe`-level fixme instances to the `it` level.

PR Close #27354
This commit is contained in:
Kristiyan Kostadinov 2018-11-29 23:34:28 +01:00 committed by Igor Minar
parent 36e7bf1b7b
commit 23bc8edf24
11 changed files with 1566 additions and 1451 deletions

View File

@ -84,7 +84,7 @@ class NestedAsyncTimeoutComp {
} }
{ {
fixmeIvy('unknown') && describe('ComponentFixture', () => { describe('ComponentFixture', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ declarations: [
@ -94,7 +94,7 @@ class NestedAsyncTimeoutComp {
}); });
})); }));
it('should auto detect changes if autoDetectChanges is called', () => { fixmeIvy('unknown') && it('should auto detect changes if autoDetectChanges is called', () => {
const componentFixture = TestBed.createComponent(AutoDetectComp); const componentFixture = TestBed.createComponent(AutoDetectComp);
expect(componentFixture.ngZone).not.toBeNull(); expect(componentFixture.ngZone).not.toBeNull();
@ -108,181 +108,192 @@ class NestedAsyncTimeoutComp {
expect(componentFixture.nativeElement).toHaveText('11'); expect(componentFixture.nativeElement).toHaveText('11');
}); });
it('should auto detect changes if ComponentFixtureAutoDetect is provided as true', fixmeIvy('unknown') &&
withModule({providers: [{provide: ComponentFixtureAutoDetect, useValue: true}]}, () => { it('should auto detect changes if ComponentFixtureAutoDetect is provided as true',
withModule({providers: [{provide: ComponentFixtureAutoDetect, useValue: true}]}, () => {
const componentFixture = TestBed.createComponent(AutoDetectComp); const componentFixture = TestBed.createComponent(AutoDetectComp);
expect(componentFixture.nativeElement).toHaveText('1'); expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0]; const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click'); dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('11');
}));
it('should signal through whenStable when the fixture is stable (autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(AsyncComp);
componentFixture.autoDetectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become stable
// before checking for new value.
expect(componentFixture.isStable()).toBe(false);
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
it('should signal through isStable when the fixture is stable (no autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(AsyncComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become stable
// before checking.
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
it('should wait for macroTask(setTimeout) while checking for whenStable ' +
'(autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(AsyncTimeoutComp);
componentFixture.autoDetectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become
// stable before checking for new value.
expect(componentFixture.isStable()).toBe(false);
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
it('should wait for macroTask(setTimeout) while checking for whenStable ' +
'(no autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(AsyncTimeoutComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become
// stable before checking for new value.
expect(componentFixture.isStable()).toBe(false);
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' +
'(autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp);
componentFixture.autoDetectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become
// stable before checking for new value.
expect(componentFixture.isStable()).toBe(false);
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' +
'(no autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become
// stable before checking for new value.
expect(componentFixture.isStable()).toBe(false);
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
it('should stabilize after async task in change detection (autoDetectChanges)', async(() => {
const componentFixture = TestBed.createComponent(AsyncChangeComp);
componentFixture.autoDetectChanges();
componentFixture.whenStable().then((_) => {
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
componentFixture.whenStable().then(
(_) => { expect(componentFixture.nativeElement).toHaveText('11'); });
});
}));
it('should stabilize after async task in change detection(no autoDetectChanges)', async(() => {
const componentFixture = TestBed.createComponent(AsyncChangeComp);
componentFixture.detectChanges();
componentFixture.whenStable().then((_) => {
// Run detectChanges again so that stabilized value is reflected in the
// DOM.
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
componentFixture.detectChanges();
componentFixture.whenStable().then((_) => {
// Run detectChanges again so that stabilized value is reflected in
// the DOM.
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('11'); expect(componentFixture.nativeElement).toHaveText('11');
}); }));
});
})); fixmeIvy('unknown') &&
it('should signal through whenStable when the fixture is stable (autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(AsyncComp);
componentFixture.autoDetectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become stable
// before checking for new value.
expect(componentFixture.isStable()).toBe(false);
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
fixmeIvy('unknown') &&
it('should signal through isStable when the fixture is stable (no autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(AsyncComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become stable
// before checking.
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
fixmeIvy('unknown') &&
it('should wait for macroTask(setTimeout) while checking for whenStable ' +
'(autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(AsyncTimeoutComp);
componentFixture.autoDetectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become
// stable before checking for new value.
expect(componentFixture.isStable()).toBe(false);
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
fixmeIvy('unknown') &&
it('should wait for macroTask(setTimeout) while checking for whenStable ' +
'(no autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(AsyncTimeoutComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become
// stable before checking for new value.
expect(componentFixture.isStable()).toBe(false);
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
fixmeIvy('unknown') &&
it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' +
'(autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp);
componentFixture.autoDetectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become
// stable before checking for new value.
expect(componentFixture.isStable()).toBe(false);
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
fixmeIvy('unknown') &&
it('should wait for nested macroTasks(setTimeout) while checking for whenStable ' +
'(no autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(NestedAsyncTimeoutComp);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
expect(componentFixture.nativeElement).toHaveText('1');
// Component is updated asynchronously. Wait for the fixture to become
// stable before checking for new value.
expect(componentFixture.isStable()).toBe(false);
componentFixture.whenStable().then((waited) => {
expect(waited).toBe(true);
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('11');
});
}));
fixmeIvy('unknown') &&
it('should stabilize after async task in change detection (autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(AsyncChangeComp);
componentFixture.autoDetectChanges();
componentFixture.whenStable().then((_) => {
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
componentFixture.whenStable().then(
(_) => { expect(componentFixture.nativeElement).toHaveText('11'); });
});
}));
fixmeIvy('unknown') &&
it('should stabilize after async task in change detection(no autoDetectChanges)',
async(() => {
const componentFixture = TestBed.createComponent(AsyncChangeComp);
componentFixture.detectChanges();
componentFixture.whenStable().then((_) => {
// Run detectChanges again so that stabilized value is reflected in the
// DOM.
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('1');
const element = componentFixture.debugElement.children[0];
dispatchEvent(element.nativeElement, 'click');
componentFixture.detectChanges();
componentFixture.whenStable().then((_) => {
// Run detectChanges again so that stabilized value is reflected in
// the DOM.
componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('11');
});
});
}));
describe('No NgZone', () => { describe('No NgZone', () => {
beforeEach(() => { beforeEach(() => {
@ -290,7 +301,7 @@ class NestedAsyncTimeoutComp {
{providers: [{provide: ComponentFixtureNoNgZone, useValue: true}]}); {providers: [{provide: ComponentFixtureNoNgZone, useValue: true}]});
}); });
it('calling autoDetectChanges raises an error', () => { fixmeIvy('unknown') && it('calling autoDetectChanges raises an error', () => {
const componentFixture = TestBed.createComponent(SimpleComp); const componentFixture = TestBed.createComponent(SimpleComp);
expect(() => { expect(() => {
@ -298,27 +309,28 @@ class NestedAsyncTimeoutComp {
}).toThrowError(/Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set/); }).toThrowError(/Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set/);
}); });
it('should instantiate a component with valid DOM', async(() => { fixmeIvy('unknown') &&
it('should instantiate a component with valid DOM', async(() => {
const componentFixture = TestBed.createComponent(SimpleComp); const componentFixture = TestBed.createComponent(SimpleComp);
expect(componentFixture.ngZone).toBeNull(); expect(componentFixture.ngZone).toBeNull();
componentFixture.detectChanges(); componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('Original Simple'); expect(componentFixture.nativeElement).toHaveText('Original Simple');
})); }));
it('should allow changing members of the component', async(() => { fixmeIvy('unknown') && it('should allow changing members of the component', async(() => {
const componentFixture = TestBed.createComponent(MyIfComp); const componentFixture = TestBed.createComponent(MyIfComp);
componentFixture.detectChanges(); componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('MyIf()'); expect(componentFixture.nativeElement).toHaveText('MyIf()');
componentFixture.componentInstance.showMore = true; componentFixture.componentInstance.showMore = true;
componentFixture.detectChanges(); componentFixture.detectChanges();
expect(componentFixture.nativeElement).toHaveText('MyIf(More)'); expect(componentFixture.nativeElement).toHaveText('MyIf(More)');
})); }));
}); });
}); });

View File

@ -169,7 +169,7 @@ class TestApp {
} }
{ {
fixmeIvy('unknown') && describe('debug element', () => { describe('debug element', () => {
let fixture: ComponentFixture<any>; let fixture: ComponentFixture<any>;
beforeEach(async(() => { beforeEach(async(() => {
@ -192,13 +192,13 @@ class TestApp {
}); });
})); }));
it('should list all child nodes', () => { fixmeIvy('unknown') && it('should list all child nodes', () => {
fixture = TestBed.createComponent(ParentComp); fixture = TestBed.createComponent(ParentComp);
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.childNodes.length).toEqual(3); expect(fixture.debugElement.childNodes.length).toEqual(3);
}); });
it('should list all component child elements', () => { fixmeIvy('unknown') && it('should list all component child elements', () => {
fixture = TestBed.createComponent(ParentComp); fixture = TestBed.createComponent(ParentComp);
fixture.detectChanges(); fixture.detectChanges();
const childEls = fixture.debugElement.children; const childEls = fixture.debugElement.children;
@ -225,7 +225,7 @@ class TestApp {
expect(getDOM().hasClass(childNested[0].nativeElement, 'childnested')).toBe(true); expect(getDOM().hasClass(childNested[0].nativeElement, 'childnested')).toBe(true);
}); });
it('should list conditional component child elements', () => { fixmeIvy('unknown') && it('should list conditional component child elements', () => {
fixture = TestBed.createComponent(ConditionalParentComp); fixture = TestBed.createComponent(ConditionalParentComp);
fixture.detectChanges(); fixture.detectChanges();
@ -246,7 +246,7 @@ class TestApp {
expect(conditionalContentComp.children.length).toEqual(1); expect(conditionalContentComp.children.length).toEqual(1);
}); });
it('should list child elements within viewports', () => { fixmeIvy('unknown') && it('should list child elements within viewports', () => {
fixture = TestBed.createComponent(UsingFor); fixture = TestBed.createComponent(UsingFor);
fixture.detectChanges(); fixture.detectChanges();
@ -259,7 +259,7 @@ class TestApp {
expect(list.children.length).toEqual(3); expect(list.children.length).toEqual(3);
}); });
it('should list element attributes', () => { fixmeIvy('unknown') && it('should list element attributes', () => {
fixture = TestBed.createComponent(TestApp); fixture = TestBed.createComponent(TestApp);
fixture.detectChanges(); fixture.detectChanges();
const bankElem = fixture.debugElement.children[0]; const bankElem = fixture.debugElement.children[0];
@ -268,7 +268,7 @@ class TestApp {
expect(bankElem.attributes['account']).toEqual('4747'); expect(bankElem.attributes['account']).toEqual('4747');
}); });
it('should list element classes', () => { fixmeIvy('unknown') && it('should list element classes', () => {
fixture = TestBed.createComponent(TestApp); fixture = TestBed.createComponent(TestApp);
fixture.detectChanges(); fixture.detectChanges();
const bankElem = fixture.debugElement.children[0]; const bankElem = fixture.debugElement.children[0];
@ -277,7 +277,7 @@ class TestApp {
expect(bankElem.classes['open']).toBe(false); expect(bankElem.classes['open']).toBe(false);
}); });
it('should list element styles', () => { fixmeIvy('unknown') && it('should list element styles', () => {
fixture = TestBed.createComponent(TestApp); fixture = TestBed.createComponent(TestApp);
fixture.detectChanges(); fixture.detectChanges();
const bankElem = fixture.debugElement.children[0]; const bankElem = fixture.debugElement.children[0];
@ -286,7 +286,7 @@ class TestApp {
expect(bankElem.styles['color']).toEqual('red'); expect(bankElem.styles['color']).toEqual('red');
}); });
it('should query child elements by css', () => { fixmeIvy('unknown') && it('should query child elements by css', () => {
fixture = TestBed.createComponent(ParentComp); fixture = TestBed.createComponent(ParentComp);
fixture.detectChanges(); fixture.detectChanges();
@ -296,7 +296,7 @@ class TestApp {
expect(getDOM().hasClass(childTestEls[0].nativeElement, 'child-comp-class')).toBe(true); expect(getDOM().hasClass(childTestEls[0].nativeElement, 'child-comp-class')).toBe(true);
}); });
it('should query child elements by directive', () => { fixmeIvy('unknown') && it('should query child elements by directive', () => {
fixture = TestBed.createComponent(ParentComp); fixture = TestBed.createComponent(ParentComp);
fixture.detectChanges(); fixture.detectChanges();
@ -309,21 +309,21 @@ class TestApp {
expect(getDOM().hasClass(childTestEls[3].nativeElement, 'childnested')).toBe(true); expect(getDOM().hasClass(childTestEls[3].nativeElement, 'childnested')).toBe(true);
}); });
it('should list providerTokens', () => { fixmeIvy('unknown') && it('should list providerTokens', () => {
fixture = TestBed.createComponent(ParentComp); fixture = TestBed.createComponent(ParentComp);
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.providerTokens).toContain(Logger); expect(fixture.debugElement.providerTokens).toContain(Logger);
}); });
it('should list locals', () => { fixmeIvy('unknown') && it('should list locals', () => {
fixture = TestBed.createComponent(LocalsComp); fixture = TestBed.createComponent(LocalsComp);
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.children[0].references !['alice']).toBeAnInstanceOf(MyDir); expect(fixture.debugElement.children[0].references !['alice']).toBeAnInstanceOf(MyDir);
}); });
it('should allow injecting from the element injector', () => { fixmeIvy('unknown') && it('should allow injecting from the element injector', () => {
fixture = TestBed.createComponent(ParentComp); fixture = TestBed.createComponent(ParentComp);
fixture.detectChanges(); fixture.detectChanges();
@ -332,7 +332,7 @@ class TestApp {
]); ]);
}); });
it('should list event listeners', () => { fixmeIvy('unknown') && it('should list event listeners', () => {
fixture = TestBed.createComponent(EventsComp); fixture = TestBed.createComponent(EventsComp);
fixture.detectChanges(); fixture.detectChanges();
@ -341,7 +341,7 @@ class TestApp {
}); });
it('should trigger event handlers', () => { fixmeIvy('unknown') && it('should trigger event handlers', () => {
fixture = TestBed.createComponent(EventsComp); fixture = TestBed.createComponent(EventsComp);
fixture.detectChanges(); fixture.detectChanges();

View File

@ -13,7 +13,7 @@ import {Log} from '@angular/core/testing/src/testing_internal';
import {fixmeIvy} from '@angular/private/testing'; import {fixmeIvy} from '@angular/private/testing';
{ {
fixmeIvy('unknown') && describe('directive lifecycle integration spec', () => { describe('directive lifecycle integration spec', () => {
let log: Log; let log: Log;
beforeEach(() => { beforeEach(() => {
@ -31,22 +31,23 @@ import {fixmeIvy} from '@angular/private/testing';
beforeEach(inject([Log], (_log: any) => { log = _log; })); beforeEach(inject([Log], (_log: any) => { log = _log; }));
it('should invoke lifecycle methods ngOnChanges > ngOnInit > ngDoCheck > ngAfterContentChecked', fixmeIvy('unknown') &&
() => { it('should invoke lifecycle methods ngOnChanges > ngOnInit > ngDoCheck > ngAfterContentChecked',
const fixture = TestBed.createComponent(MyComp5); () => {
fixture.detectChanges(); const fixture = TestBed.createComponent(MyComp5);
fixture.detectChanges();
expect(log.result()) expect(log.result())
.toEqual( .toEqual(
'ngOnChanges; ngOnInit; ngDoCheck; ngAfterContentInit; ngAfterContentChecked; child_ngDoCheck; ' + 'ngOnChanges; ngOnInit; ngDoCheck; ngAfterContentInit; ngAfterContentChecked; child_ngDoCheck; ' +
'ngAfterViewInit; ngAfterViewChecked'); 'ngAfterViewInit; ngAfterViewChecked');
log.clear(); log.clear();
fixture.detectChanges(); fixture.detectChanges();
expect(log.result()) expect(log.result())
.toEqual('ngDoCheck; ngAfterContentChecked; child_ngDoCheck; ngAfterViewChecked'); .toEqual('ngDoCheck; ngAfterContentChecked; child_ngDoCheck; ngAfterViewChecked');
}); });
}); });
} }

View File

@ -18,32 +18,33 @@ const resolvedPromise = Promise.resolve(null);
const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec']; const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec'];
{ {
fixmeIvy('unknown') && describe('fake async', () => { describe('fake async', () => {
it('should run synchronous code', () => { fixmeIvy('unknown') && it('should run synchronous code', () => {
let ran = false; let ran = false;
fakeAsync(() => { ran = true; })(); fakeAsync(() => { ran = true; })();
expect(ran).toEqual(true); expect(ran).toEqual(true);
}); });
it('should pass arguments to the wrapped function', () => { fixmeIvy('unknown') && it('should pass arguments to the wrapped function', () => {
fakeAsync((foo: any /** TODO #9100 */, bar: any /** TODO #9100 */) => { fakeAsync((foo: any /** TODO #9100 */, bar: any /** TODO #9100 */) => {
expect(foo).toEqual('foo'); expect(foo).toEqual('foo');
expect(bar).toEqual('bar'); expect(bar).toEqual('bar');
})('foo', 'bar'); })('foo', 'bar');
}); });
it('should work with inject()', fakeAsync(inject([Parser], (parser: any /** TODO #9100 */) => { fixmeIvy('unknown') && it('should work with inject()',
expect(parser).toBeAnInstanceOf(Parser); fakeAsync(inject([Parser], (parser: any /** TODO #9100 */) => {
}))); expect(parser).toBeAnInstanceOf(Parser);
})));
it('should throw on nested calls', () => { fixmeIvy('unknown') && it('should throw on nested calls', () => {
expect(() => { expect(() => {
fakeAsync(() => { fakeAsync((): any /** TODO #9100 */ => null)(); })(); fakeAsync(() => { fakeAsync((): any /** TODO #9100 */ => null)(); })();
}).toThrowError('fakeAsync() calls can not be nested'); }).toThrowError('fakeAsync() calls can not be nested');
}); });
it('should flush microtasks before returning', () => { fixmeIvy('unknown') && it('should flush microtasks before returning', () => {
let thenRan = false; let thenRan = false;
fakeAsync(() => { resolvedPromise.then(_ => { thenRan = true; }); })(); fakeAsync(() => { resolvedPromise.then(_ => { thenRan = true; }); })();
@ -52,275 +53,280 @@ const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec'
}); });
it('should propagate the return value', fixmeIvy('unknown') && it('should propagate the return value',
() => { expect(fakeAsync(() => 'foo')()).toEqual('foo'); }); () => { expect(fakeAsync(() => 'foo')()).toEqual('foo'); });
describe('Promise', () => { describe('Promise', () => {
it('should run asynchronous code', fakeAsync(() => { fixmeIvy('unknown') && it('should run asynchronous code', fakeAsync(() => {
let thenRan = false; let thenRan = false;
resolvedPromise.then((_) => { thenRan = true; }); resolvedPromise.then((_) => { thenRan = true; });
expect(thenRan).toEqual(false); expect(thenRan).toEqual(false);
flushMicrotasks(); flushMicrotasks();
expect(thenRan).toEqual(true); expect(thenRan).toEqual(true);
})); }));
it('should run chained thens', fakeAsync(() => { fixmeIvy('unknown') && it('should run chained thens', fakeAsync(() => {
const log = new Log(); const log = new Log();
resolvedPromise.then((_) => log.add(1)).then((_) => log.add(2)); resolvedPromise.then((_) => log.add(1)).then((_) => log.add(2));
expect(log.result()).toEqual(''); expect(log.result()).toEqual('');
flushMicrotasks(); flushMicrotasks();
expect(log.result()).toEqual('1; 2'); expect(log.result()).toEqual('1; 2');
})); }));
it('should run Promise created in Promise', fakeAsync(() => { fixmeIvy('unknown') && it('should run Promise created in Promise', fakeAsync(() => {
const log = new Log(); const log = new Log();
resolvedPromise.then((_) => { resolvedPromise.then((_) => {
log.add(1); log.add(1);
resolvedPromise.then((_) => log.add(2)); resolvedPromise.then((_) => log.add(2));
}); });
expect(log.result()).toEqual(''); expect(log.result()).toEqual('');
flushMicrotasks(); flushMicrotasks();
expect(log.result()).toEqual('1; 2'); expect(log.result()).toEqual('1; 2');
})); }));
it('should complain if the test throws an exception during async calls', () => { fixmeIvy('unknown') &&
expect(() => { it('should complain if the test throws an exception during async calls', () => {
fakeAsync(() => { expect(() => {
resolvedPromise.then((_) => { throw new Error('async'); }); fakeAsync(() => {
flushMicrotasks(); resolvedPromise.then((_) => { throw new Error('async'); });
})(); flushMicrotasks();
}).toThrowError(/Uncaught \(in promise\): Error: async/); })();
}); }).toThrowError(/Uncaught \(in promise\): Error: async/);
});
it('should complain if a test throws an exception', () => { fixmeIvy('unknown') && it('should complain if a test throws an exception', () => {
expect(() => { fakeAsync(() => { throw new Error('sync'); })(); }).toThrowError('sync'); expect(() => { fakeAsync(() => { throw new Error('sync'); })(); }).toThrowError('sync');
}); });
}); });
describe('timers', () => { describe('timers', () => {
it('should run queued zero duration timer on zero tick', fakeAsync(() => { fixmeIvy('unknown') &&
let ran = false; it('should run queued zero duration timer on zero tick', fakeAsync(() => {
setTimeout(() => { ran = true; }, 0); let ran = false;
setTimeout(() => { ran = true; }, 0);
expect(ran).toEqual(false); expect(ran).toEqual(false);
tick(); tick();
expect(ran).toEqual(true); expect(ran).toEqual(true);
})); }));
it('should run queued timer after sufficient clock ticks', fakeAsync(() => { fixmeIvy('unknown') &&
let ran = false; it('should run queued timer after sufficient clock ticks', fakeAsync(() => {
setTimeout(() => { ran = true; }, 10); let ran = false;
setTimeout(() => { ran = true; }, 10);
tick(6); tick(6);
expect(ran).toEqual(false); expect(ran).toEqual(false);
tick(6); tick(6);
expect(ran).toEqual(true); expect(ran).toEqual(true);
})); }));
it('should run queued timer only once', fakeAsync(() => { fixmeIvy('unknown') && it('should run queued timer only once', fakeAsync(() => {
let cycles = 0; let cycles = 0;
setTimeout(() => { cycles++; }, 10); setTimeout(() => { cycles++; }, 10);
tick(10); tick(10);
expect(cycles).toEqual(1); expect(cycles).toEqual(1);
tick(10); tick(10);
expect(cycles).toEqual(1); expect(cycles).toEqual(1);
tick(10); tick(10);
expect(cycles).toEqual(1); expect(cycles).toEqual(1);
})); }));
it('should not run cancelled timer', fakeAsync(() => { fixmeIvy('unknown') && it('should not run cancelled timer', fakeAsync(() => {
let ran = false; let ran = false;
const id = setTimeout(() => { ran = true; }, 10); const id = setTimeout(() => { ran = true; }, 10);
clearTimeout(id); clearTimeout(id);
tick(10); tick(10);
expect(ran).toEqual(false); expect(ran).toEqual(false);
})); }));
it('should throw an error on dangling timers', () => { fixmeIvy('unknown') && it('should throw an error on dangling timers', () => {
expect(() => { expect(() => {
fakeAsync(() => { setTimeout(() => {}, 10); })(); fakeAsync(() => { setTimeout(() => {}, 10); })();
}).toThrowError('1 timer(s) still in the queue.'); }).toThrowError('1 timer(s) still in the queue.');
}); });
it('should throw an error on dangling periodic timers', () => { fixmeIvy('unknown') && it('should throw an error on dangling periodic timers', () => {
expect(() => { expect(() => {
fakeAsync(() => { setInterval(() => {}, 10); })(); fakeAsync(() => { setInterval(() => {}, 10); })();
}).toThrowError('1 periodic timer(s) still in the queue.'); }).toThrowError('1 periodic timer(s) still in the queue.');
}); });
it('should run periodic timers', fakeAsync(() => { fixmeIvy('unknown') && it('should run periodic timers', fakeAsync(() => {
let cycles = 0; let cycles = 0;
const id = setInterval(() => { cycles++; }, 10); const id = setInterval(() => { cycles++; }, 10);
tick(10); tick(10);
expect(cycles).toEqual(1); expect(cycles).toEqual(1);
tick(10); tick(10);
expect(cycles).toEqual(2); expect(cycles).toEqual(2);
tick(10); tick(10);
expect(cycles).toEqual(3); expect(cycles).toEqual(3);
clearInterval(id); clearInterval(id);
})); }));
it('should not run cancelled periodic timer', fakeAsync(() => { fixmeIvy('unknown') && it('should not run cancelled periodic timer', fakeAsync(() => {
let ran = false; let ran = false;
const id = setInterval(() => { ran = true; }, 10); const id = setInterval(() => { ran = true; }, 10);
clearInterval(id); clearInterval(id);
tick(10); tick(10);
expect(ran).toEqual(false); expect(ran).toEqual(false);
})); }));
it('should be able to cancel periodic timers from a callback', fakeAsync(() => { fixmeIvy('unknown') &&
let cycles = 0; it('should be able to cancel periodic timers from a callback', fakeAsync(() => {
let id: any /** TODO #9100 */; let cycles = 0;
let id: any /** TODO #9100 */;
id = setInterval(() => { id = setInterval(() => {
cycles++; cycles++;
clearInterval(id); clearInterval(id);
}, 10); }, 10);
tick(10); tick(10);
expect(cycles).toEqual(1); expect(cycles).toEqual(1);
tick(10); tick(10);
expect(cycles).toEqual(1); expect(cycles).toEqual(1);
})); }));
it('should clear periodic timers', fakeAsync(() => { fixmeIvy('unknown') && it('should clear periodic timers', fakeAsync(() => {
let cycles = 0; let cycles = 0;
const id = setInterval(() => { cycles++; }, 10); const id = setInterval(() => { cycles++; }, 10);
tick(10); tick(10);
expect(cycles).toEqual(1); expect(cycles).toEqual(1);
discardPeriodicTasks(); discardPeriodicTasks();
// Tick once to clear out the timer which already started. // Tick once to clear out the timer which already started.
tick(10); tick(10);
expect(cycles).toEqual(2); expect(cycles).toEqual(2);
tick(10); tick(10);
// Nothing should change // Nothing should change
expect(cycles).toEqual(2); expect(cycles).toEqual(2);
})); }));
it('should process microtasks before timers', fakeAsync(() => { fixmeIvy('unknown') && it('should process microtasks before timers', fakeAsync(() => {
const log = new Log(); const log = new Log();
resolvedPromise.then((_) => log.add('microtask')); resolvedPromise.then((_) => log.add('microtask'));
setTimeout(() => log.add('timer'), 9); setTimeout(() => log.add('timer'), 9);
const id = setInterval(() => log.add('periodic timer'), 10); const id = setInterval(() => log.add('periodic timer'), 10);
expect(log.result()).toEqual(''); expect(log.result()).toEqual('');
tick(10); tick(10);
expect(log.result()).toEqual('microtask; timer; periodic timer'); expect(log.result()).toEqual('microtask; timer; periodic timer');
clearInterval(id); clearInterval(id);
})); }));
it('should process micro-tasks created in timers before next timers', fakeAsync(() => { fixmeIvy('unknown') &&
const log = new Log(); it('should process micro-tasks created in timers before next timers', fakeAsync(() => {
const log = new Log();
resolvedPromise.then((_) => log.add('microtask')); resolvedPromise.then((_) => log.add('microtask'));
setTimeout(() => { setTimeout(() => {
log.add('timer'); log.add('timer');
resolvedPromise.then((_) => log.add('t microtask')); resolvedPromise.then((_) => log.add('t microtask'));
}, 9); }, 9);
const id = setInterval(() => { const id = setInterval(() => {
log.add('periodic timer'); log.add('periodic timer');
resolvedPromise.then((_) => log.add('pt microtask')); resolvedPromise.then((_) => log.add('pt microtask'));
}, 10); }, 10);
tick(10); tick(10);
expect(log.result()) expect(log.result())
.toEqual('microtask; timer; t microtask; periodic timer; pt microtask'); .toEqual('microtask; timer; t microtask; periodic timer; pt microtask');
tick(10); tick(10);
expect(log.result()) expect(log.result())
.toEqual( .toEqual(
'microtask; timer; t microtask; periodic timer; pt microtask; periodic timer; pt microtask'); 'microtask; timer; t microtask; periodic timer; pt microtask; periodic timer; pt microtask');
clearInterval(id); clearInterval(id);
})); }));
it('should flush tasks', fakeAsync(() => { fixmeIvy('unknown') && it('should flush tasks', fakeAsync(() => {
let ran = false; let ran = false;
setTimeout(() => { ran = true; }, 10); setTimeout(() => { ran = true; }, 10);
flush(); flush();
expect(ran).toEqual(true); expect(ran).toEqual(true);
})); }));
it('should flush multiple tasks', fakeAsync(() => { fixmeIvy('unknown') && it('should flush multiple tasks', fakeAsync(() => {
let ran = false; let ran = false;
let ran2 = false; let ran2 = false;
setTimeout(() => { ran = true; }, 10); setTimeout(() => { ran = true; }, 10);
setTimeout(() => { ran2 = true; }, 30); setTimeout(() => { ran2 = true; }, 30);
let elapsed = flush(); let elapsed = flush();
expect(ran).toEqual(true); expect(ran).toEqual(true);
expect(ran2).toEqual(true); expect(ran2).toEqual(true);
expect(elapsed).toEqual(30); expect(elapsed).toEqual(30);
})); }));
it('should move periodic tasks', fakeAsync(() => { fixmeIvy('unknown') && it('should move periodic tasks', fakeAsync(() => {
let ran = false; let ran = false;
let count = 0; let count = 0;
setInterval(() => { count++; }, 10); setInterval(() => { count++; }, 10);
setTimeout(() => { ran = true; }, 35); setTimeout(() => { ran = true; }, 35);
let elapsed = flush(); let elapsed = flush();
expect(count).toEqual(3); expect(count).toEqual(3);
expect(ran).toEqual(true); expect(ran).toEqual(true);
expect(elapsed).toEqual(35); expect(elapsed).toEqual(35);
discardPeriodicTasks(); discardPeriodicTasks();
})); }));
}); });
describe('outside of the fakeAsync zone', () => { describe('outside of the fakeAsync zone', () => {
it('calling flushMicrotasks should throw', () => { fixmeIvy('unknown') && it('calling flushMicrotasks should throw', () => {
expect(() => { expect(() => {
flushMicrotasks(); flushMicrotasks();
}).toThrowError('The code should be running in the fakeAsync zone to call this function'); }).toThrowError('The code should be running in the fakeAsync zone to call this function');
}); });
it('calling tick should throw', () => { fixmeIvy('unknown') && it('calling tick should throw', () => {
expect(() => { expect(() => {
tick(); tick();
}).toThrowError('The code should be running in the fakeAsync zone to call this function'); }).toThrowError('The code should be running in the fakeAsync zone to call this function');
}); });
it('calling flush should throw', () => { fixmeIvy('unknown') && it('calling flush should throw', () => {
expect(() => { expect(() => {
flush(); flush();
}).toThrowError('The code should be running in the fakeAsync zone to call this function'); }).toThrowError('The code should be running in the fakeAsync zone to call this function');
}); });
it('calling discardPeriodicTasks should throw', () => { fixmeIvy('unknown') && it('calling discardPeriodicTasks should throw', () => {
expect(() => { expect(() => {
discardPeriodicTasks(); discardPeriodicTasks();
}).toThrowError('The code should be running in the fakeAsync zone to call this function'); }).toThrowError('The code should be running in the fakeAsync zone to call this function');
@ -332,10 +338,10 @@ const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec'
let zoneInTest1: Zone; let zoneInTest1: Zone;
beforeEach(fakeAsync(() => { zoneInBeforeEach = Zone.current; })); beforeEach(fakeAsync(() => { zoneInBeforeEach = Zone.current; }));
it('should use the same zone as in beforeEach', fakeAsync(() => { fixmeIvy('unknown') && it('should use the same zone as in beforeEach', fakeAsync(() => {
zoneInTest1 = Zone.current; zoneInTest1 = Zone.current;
expect(zoneInTest1).toBe(zoneInBeforeEach); expect(zoneInTest1).toBe(zoneInBeforeEach);
})); }));
}); });
}); });
@ -344,19 +350,21 @@ const ProxyZoneSpec: {assertPresent: () => void} = (Zone as any)['ProxyZoneSpec'
afterEach(() => { ProxyZoneSpec.assertPresent(); }); afterEach(() => { ProxyZoneSpec.assertPresent(); });
it('should allow fakeAsync zone to retroactively set a zoneSpec outside of fakeAsync', () => { fixmeIvy('unknown') &&
ProxyZoneSpec.assertPresent(); it('should allow fakeAsync zone to retroactively set a zoneSpec outside of fakeAsync',
let state: string = 'not run'; () => {
const testZone = Zone.current.fork({name: 'test-zone'}); ProxyZoneSpec.assertPresent();
(fakeAsync(() => { let state: string = 'not run';
testZone.run(() => { const testZone = Zone.current.fork({name: 'test-zone'});
Promise.resolve('works').then((v) => state = v); (fakeAsync(() => {
expect(state).toEqual('not run'); testZone.run(() => {
flushMicrotasks(); Promise.resolve('works').then((v) => state = v);
expect(state).toEqual('works'); expect(state).toEqual('not run');
}); flushMicrotasks();
}))(); expect(state).toEqual('works');
expect(state).toEqual('works'); });
}); }))();
expect(state).toEqual('works');
});
}); });
} }

View File

@ -13,15 +13,17 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
import {fixmeIvy} from '@angular/private/testing'; import {fixmeIvy} from '@angular/private/testing';
{ {
fixmeIvy('unknown') && describe('forwardRef integration', function() { describe('forwardRef integration', function() {
beforeEach(() => { TestBed.configureTestingModule({imports: [Module], declarations: [App]}); }); beforeEach(() => { TestBed.configureTestingModule({imports: [Module], declarations: [App]}); });
it('should instantiate components which are declared using forwardRef', () => { fixmeIvy('unknown') &&
const a = TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}).createComponent(App); it('should instantiate components which are declared using forwardRef', () => {
a.detectChanges(); const a =
expect(asNativeElements(a.debugElement.children)).toHaveText('frame(lock)'); TestBed.configureTestingModule({schemas: [NO_ERRORS_SCHEMA]}).createComponent(App);
expect(TestBed.get(ModuleFrame)).toBeDefined(); a.detectChanges();
}); expect(asNativeElements(a.debugElement.children)).toHaveText('frame(lock)');
expect(TestBed.get(ModuleFrame)).toBeDefined();
});
}); });
} }

View File

@ -16,7 +16,7 @@ import {fixmeIvy} from '@angular/private/testing';
{ {
// ivy fix in https://github.com/angular/angular/pull/26871 // ivy fix in https://github.com/angular/angular/pull/26871
fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') && describe('Jit Summaries', () => { describe('Jit Summaries', () => {
let instances: Map<any, Base>; let instances: Map<any, Base>;
let summaries: () => any[]; let summaries: () => any[];
@ -138,146 +138,160 @@ import {fixmeIvy} from '@angular/private/testing';
afterEach(() => { resetTestEnvironmentWithSummaries(); }); afterEach(() => { resetTestEnvironmentWithSummaries(); });
it('should use directive metadata from summaries', () => { fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
resetTestEnvironmentWithSummaries(summaries); it('should use directive metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
@Component({template: '<div someDir></div>'}) @Component({template: '<div someDir></div>'})
class TestComp { class TestComp {
} }
TestBed TestBed
.configureTestingModule({providers: [SomeDep], declarations: [TestComp, SomeDirective]}) .configureTestingModule(
.createComponent(TestComp); {providers: [SomeDep], declarations: [TestComp, SomeDirective]})
expectInstanceCreated(SomeDirective); .createComponent(TestComp);
}); expectInstanceCreated(SomeDirective);
});
it('should use pipe metadata from summaries', () => { fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
resetTestEnvironmentWithSummaries(summaries); it('should use pipe metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
@Component({template: '{{1 | somePipe}}'}) @Component({template: '{{1 | somePipe}}'})
class TestComp { class TestComp {
} }
TestBed.configureTestingModule({providers: [SomeDep], declarations: [TestComp, SomePipe]}) TestBed.configureTestingModule({providers: [SomeDep], declarations: [TestComp, SomePipe]})
.createComponent(TestComp); .createComponent(TestComp);
expectInstanceCreated(SomePipe); expectInstanceCreated(SomePipe);
}); });
it('should use Service metadata from summaries', () => { fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
resetTestEnvironmentWithSummaries(summaries); it('should use Service metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.configureTestingModule({ TestBed.configureTestingModule({
providers: [SomeService, SomeDep], providers: [SomeService, SomeDep],
}); });
TestBed.get(SomeService); TestBed.get(SomeService);
expectInstanceCreated(SomeService); expectInstanceCreated(SomeService);
}); });
it('should use NgModule metadata from summaries', () => { fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
resetTestEnvironmentWithSummaries(summaries); it('should use NgModule metadata from summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed TestBed
.configureTestingModule( .configureTestingModule(
{providers: [SomeDep], declarations: [TestComp3], imports: [SomeModule]}) {providers: [SomeDep], declarations: [TestComp3], imports: [SomeModule]})
.createComponent(TestComp3); .createComponent(TestComp3);
expectInstanceCreated(SomeModule); expectInstanceCreated(SomeModule);
expectInstanceCreated(SomeDirective); expectInstanceCreated(SomeDirective);
expectInstanceCreated(SomePipe); expectInstanceCreated(SomePipe);
expectInstanceCreated(SomeService); expectInstanceCreated(SomeService);
}); });
it('should allow to create private components from imported NgModule summaries', () => { fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
resetTestEnvironmentWithSummaries(summaries); it('should allow to create private components from imported NgModule summaries', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]}) TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent(SomePrivateComponent); .createComponent(SomePrivateComponent);
expectInstanceCreated(SomePrivateComponent); expectInstanceCreated(SomePrivateComponent);
}); });
it('should throw when trying to mock a type with a summary', () => { fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
resetTestEnvironmentWithSummaries(summaries); it('should throw when trying to mock a type with a summary', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.resetTestingModule(); TestBed.resetTestingModule();
expect(() => TestBed.overrideComponent(SomePrivateComponent, {add: {}}).compileComponents()) expect(
.toThrowError( () => TestBed.overrideComponent(SomePrivateComponent, {add: {}}).compileComponents())
'SomePrivateComponent was AOT compiled, so its metadata cannot be changed.'); .toThrowError(
TestBed.resetTestingModule(); 'SomePrivateComponent was AOT compiled, so its metadata cannot be changed.');
expect(() => TestBed.overrideDirective(SomeDirective, {add: {}}).compileComponents()) TestBed.resetTestingModule();
.toThrowError('SomeDirective was AOT compiled, so its metadata cannot be changed.'); expect(() => TestBed.overrideDirective(SomeDirective, {add: {}}).compileComponents())
TestBed.resetTestingModule(); .toThrowError('SomeDirective was AOT compiled, so its metadata cannot be changed.');
expect(() => TestBed.overridePipe(SomePipe, {add: {name: 'test'}}).compileComponents()) TestBed.resetTestingModule();
.toThrowError('SomePipe was AOT compiled, so its metadata cannot be changed.'); expect(() => TestBed.overridePipe(SomePipe, {add: {name: 'test'}}).compileComponents())
TestBed.resetTestingModule(); .toThrowError('SomePipe was AOT compiled, so its metadata cannot be changed.');
expect(() => TestBed.overrideModule(SomeModule, {add: {}}).compileComponents()) TestBed.resetTestingModule();
.toThrowError('SomeModule was AOT compiled, so its metadata cannot be changed.'); expect(() => TestBed.overrideModule(SomeModule, {add: {}}).compileComponents())
}); .toThrowError('SomeModule was AOT compiled, so its metadata cannot be changed.');
});
it('should return stack trace and component data on resetTestingModule when error is thrown', fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
() => { it('should return stack trace and component data on resetTestingModule when error is thrown',
resetTestEnvironmentWithSummaries(); () => {
resetTestEnvironmentWithSummaries();
const fixture = TestBed.configureTestingModule({declarations: [TestCompErrorOnDestroy]}) const fixture =
.createComponent<TestCompErrorOnDestroy>(TestCompErrorOnDestroy); TestBed.configureTestingModule({declarations: [TestCompErrorOnDestroy]})
.createComponent<TestCompErrorOnDestroy>(TestCompErrorOnDestroy);
const expectedError = 'Error from ngOnDestroy'; const expectedError = 'Error from ngOnDestroy';
const component: TestCompErrorOnDestroy = fixture.componentInstance; const component: TestCompErrorOnDestroy = fixture.componentInstance;
spyOn(console, 'error'); spyOn(console, 'error');
spyOn(component, 'ngOnDestroy').and.throwError(expectedError); spyOn(component, 'ngOnDestroy').and.throwError(expectedError);
const expectedObject = { const expectedObject = {
stacktrace: new Error(expectedError), stacktrace: new Error(expectedError),
component, component,
}; };
TestBed.resetTestingModule(); TestBed.resetTestingModule();
expect(console.error) expect(console.error)
.toHaveBeenCalledWith('Error during cleanup of component', expectedObject); .toHaveBeenCalledWith('Error during cleanup of component', expectedObject);
}); });
it('should allow to add summaries via configureTestingModule', () => { fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
resetTestEnvironmentWithSummaries(); it('should allow to add summaries via configureTestingModule', () => {
resetTestEnvironmentWithSummaries();
@Component({template: '<div someDir></div>'}) @Component({template: '<div someDir></div>'})
class TestComp { class TestComp {
} }
TestBed TestBed
.configureTestingModule({ .configureTestingModule({
providers: [SomeDep], providers: [SomeDep],
declarations: [TestComp, SomeDirective], declarations: [TestComp, SomeDirective],
aotSummaries: summaries aotSummaries: summaries
}) })
.createComponent(TestComp); .createComponent(TestComp);
expectInstanceCreated(SomeDirective); expectInstanceCreated(SomeDirective);
}); });
it('should allow to override a provider', () => { fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
resetTestEnvironmentWithSummaries(summaries); it('should allow to override a provider', () => {
resetTestEnvironmentWithSummaries(summaries);
const overwrittenValue = {}; const overwrittenValue = {};
const fixture = const fixture =
TestBed.overrideProvider(SomeDep, {useFactory: () => overwrittenValue, deps: []}) TestBed.overrideProvider(SomeDep, {useFactory: () => overwrittenValue, deps: []})
.configureTestingModule({providers: [SomeDep], imports: [SomeModule]}) .configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
.createComponent<SomePublicComponent>(SomePublicComponent); .createComponent<SomePublicComponent>(SomePublicComponent);
expect(fixture.componentInstance.dep).toBe(overwrittenValue); expect(fixture.componentInstance.dep).toBe(overwrittenValue);
}); });
it('should allow to override a template', () => { fixmeIvy('FW-514: ngSummary shims not generated by ngtsc') &&
resetTestEnvironmentWithSummaries(summaries); it('should allow to override a template', () => {
resetTestEnvironmentWithSummaries(summaries);
TestBed.overrideTemplateUsingTestingModule(SomePublicComponent, 'overwritten'); TestBed.overrideTemplateUsingTestingModule(SomePublicComponent, 'overwritten');
const fixture = TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]}) const fixture =
.createComponent(SomePublicComponent); TestBed.configureTestingModule({providers: [SomeDep], imports: [SomeModule]})
expectInstanceCreated(SomePublicComponent); .createComponent(SomePublicComponent);
expectInstanceCreated(SomePublicComponent);
expect(fixture.nativeElement).toHaveText('overwritten'); expect(fixture.nativeElement).toHaveText('overwritten');
}); });
}); });
} }

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ import {fixmeIvy} from '@angular/private/testing';
{ {
if (ivyEnabled) { if (ivyEnabled) {
fixmeIvy('unknown') && describe('ivy', () => { declareTests(); }); describe('ivy', () => { declareTests(); });
} else { } else {
describe('jit', () => { declareTests({useJit: true}); }); describe('jit', () => { declareTests({useJit: true}); });
describe('no jit', () => { declareTests({useJit: false}); }); describe('no jit', () => { declareTests({useJit: false}); });
@ -52,7 +52,7 @@ function declareTests(config?: {useJit: boolean}) {
afterEach(() => { getDOM().log = originalLog; }); afterEach(() => { getDOM().log = originalLog; });
describe('events', () => { describe('events', () => {
it('should disallow binding to attr.on*', () => { fixmeIvy('unknown') && it('should disallow binding to attr.on*', () => {
const template = `<div [attr.onclick]="ctxProp"></div>`; const template = `<div [attr.onclick]="ctxProp"></div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
@ -61,7 +61,7 @@ function declareTests(config?: {useJit: boolean}) {
/Binding to event attribute 'onclick' is disallowed for security reasons, please use \(click\)=.../); /Binding to event attribute 'onclick' is disallowed for security reasons, please use \(click\)=.../);
}); });
it('should disallow binding to on* with NO_ERRORS_SCHEMA', () => { fixmeIvy('unknown') && it('should disallow binding to on* with NO_ERRORS_SCHEMA', () => {
const template = `<div [onclick]="ctxProp"></div>`; const template = `<div [onclick]="ctxProp"></div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({ TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]
@ -72,29 +72,30 @@ function declareTests(config?: {useJit: boolean}) {
/Binding to event property 'onclick' is disallowed for security reasons, please use \(click\)=.../); /Binding to event property 'onclick' is disallowed for security reasons, please use \(click\)=.../);
}); });
it('should disallow binding to on* unless it is consumed by a directive', () => { fixmeIvy('unknown') &&
const template = `<div [onPrefixedProp]="ctxProp" [onclick]="ctxProp"></div>`; it('should disallow binding to on* unless it is consumed by a directive', () => {
TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({ const template = `<div [onPrefixedProp]="ctxProp" [onclick]="ctxProp"></div>`;
schemas: [NO_ERRORS_SCHEMA] TestBed.overrideComponent(SecuredComponent, {set: {template}}).configureTestingModule({
}); schemas: [NO_ERRORS_SCHEMA]
});
// should not throw for inputs starting with "on" // should not throw for inputs starting with "on"
let cmp: ComponentFixture<SecuredComponent> = undefined !; let cmp: ComponentFixture<SecuredComponent> = undefined !;
expect(() => cmp = TestBed.createComponent(SecuredComponent)).not.toThrow(); expect(() => cmp = TestBed.createComponent(SecuredComponent)).not.toThrow();
// must bind to the directive not to the property of the div // must bind to the directive not to the property of the div
const value = cmp.componentInstance.ctxProp = {}; const value = cmp.componentInstance.ctxProp = {};
cmp.detectChanges(); cmp.detectChanges();
const div = cmp.debugElement.children[0]; const div = cmp.debugElement.children[0];
expect(div.injector.get(OnPrefixDir).onclick).toBe(value); expect(div.injector.get(OnPrefixDir).onclick).toBe(value);
expect(getDOM().getProperty(div.nativeElement, 'onclick')).not.toBe(value); expect(getDOM().getProperty(div.nativeElement, 'onclick')).not.toBe(value);
expect(getDOM().hasAttribute(div.nativeElement, 'onclick')).toEqual(false); expect(getDOM().hasAttribute(div.nativeElement, 'onclick')).toEqual(false);
}); });
}); });
describe('safe HTML values', function() { describe('safe HTML values', function() {
it('should not escape values marked as trusted', () => { fixmeIvy('unknown') && it('should not escape values marked as trusted', () => {
const template = `<a [href]="ctxProp">Link Title</a>`; const template = `<a [href]="ctxProp">Link Title</a>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent); const fixture = TestBed.createComponent(SecuredComponent);
@ -108,7 +109,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().getProperty(e, 'href')).toEqual('javascript:alert(1)'); expect(getDOM().getProperty(e, 'href')).toEqual('javascript:alert(1)');
}); });
it('should error when using the wrong trusted value', () => { fixmeIvy('unknown') && it('should error when using the wrong trusted value', () => {
const template = `<a [href]="ctxProp">Link Title</a>`; const template = `<a [href]="ctxProp">Link Title</a>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent); const fixture = TestBed.createComponent(SecuredComponent);
@ -120,7 +121,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(() => fixture.detectChanges()).toThrowError(/Required a safe URL, got a Script/); expect(() => fixture.detectChanges()).toThrowError(/Required a safe URL, got a Script/);
}); });
it('should warn when using in string interpolation', () => { fixmeIvy('unknown') && it('should warn when using in string interpolation', () => {
const template = `<a href="/foo/{{ctxProp}}">Link Title</a>`; const template = `<a href="/foo/{{ctxProp}}">Link Title</a>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent); const fixture = TestBed.createComponent(SecuredComponent);
@ -153,7 +154,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(value).toEqual('unsafe:javascript:alert(1)'); expect(value).toEqual('unsafe:javascript:alert(1)');
} }
it('should escape unsafe properties', () => { fixmeIvy('unknown') && it('should escape unsafe properties', () => {
const template = `<a [href]="ctxProp">Link Title</a>`; const template = `<a [href]="ctxProp">Link Title</a>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent); const fixture = TestBed.createComponent(SecuredComponent);
@ -161,7 +162,7 @@ function declareTests(config?: {useJit: boolean}) {
checkEscapeOfHrefProperty(fixture, false); checkEscapeOfHrefProperty(fixture, false);
}); });
it('should escape unsafe attributes', () => { fixmeIvy('unknown') && it('should escape unsafe attributes', () => {
const template = `<a [attr.href]="ctxProp">Link Title</a>`; const template = `<a [attr.href]="ctxProp">Link Title</a>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent); const fixture = TestBed.createComponent(SecuredComponent);
@ -169,39 +170,41 @@ function declareTests(config?: {useJit: boolean}) {
checkEscapeOfHrefProperty(fixture, true); checkEscapeOfHrefProperty(fixture, true);
}); });
it('should escape unsafe properties if they are used in host bindings', () => { fixmeIvy('unknown') &&
@Directive({selector: '[dirHref]'}) it('should escape unsafe properties if they are used in host bindings', () => {
class HrefDirective { @Directive({selector: '[dirHref]'})
// TODO(issue/24571): remove '!'. class HrefDirective {
@HostBinding('href') @Input() // TODO(issue/24571): remove '!'.
dirHref !: string; @HostBinding('href') @Input()
} dirHref !: string;
}
const template = `<a [dirHref]="ctxProp">Link Title</a>`; const template = `<a [dirHref]="ctxProp">Link Title</a>`;
TestBed.configureTestingModule({declarations: [HrefDirective]}); TestBed.configureTestingModule({declarations: [HrefDirective]});
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent); const fixture = TestBed.createComponent(SecuredComponent);
checkEscapeOfHrefProperty(fixture, false); checkEscapeOfHrefProperty(fixture, false);
}); });
it('should escape unsafe attributes if they are used in host bindings', () => { fixmeIvy('unknown') &&
@Directive({selector: '[dirHref]'}) it('should escape unsafe attributes if they are used in host bindings', () => {
class HrefDirective { @Directive({selector: '[dirHref]'})
// TODO(issue/24571): remove '!'. class HrefDirective {
@HostBinding('attr.href') @Input() // TODO(issue/24571): remove '!'.
dirHref !: string; @HostBinding('attr.href') @Input()
} dirHref !: string;
}
const template = `<a [dirHref]="ctxProp">Link Title</a>`; const template = `<a [dirHref]="ctxProp">Link Title</a>`;
TestBed.configureTestingModule({declarations: [HrefDirective]}); TestBed.configureTestingModule({declarations: [HrefDirective]});
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent); const fixture = TestBed.createComponent(SecuredComponent);
checkEscapeOfHrefProperty(fixture, true); checkEscapeOfHrefProperty(fixture, true);
}); });
it('should escape unsafe style values', () => { fixmeIvy('unknown') && it('should escape unsafe style values', () => {
const template = `<div [style.background]="ctxProp">Text</div>`; const template = `<div [style.background]="ctxProp">Text</div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent); const fixture = TestBed.createComponent(SecuredComponent);
@ -221,7 +224,7 @@ function declareTests(config?: {useJit: boolean}) {
expect(getDOM().getStyle(e, 'background')).not.toContain('javascript'); expect(getDOM().getStyle(e, 'background')).not.toContain('javascript');
}); });
it('should escape unsafe SVG attributes', () => { fixmeIvy('unknown') && it('should escape unsafe SVG attributes', () => {
const template = `<svg:circle [xlink:href]="ctxProp">Text</svg:circle>`; const template = `<svg:circle [xlink:href]="ctxProp">Text</svg:circle>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
@ -229,7 +232,7 @@ function declareTests(config?: {useJit: boolean}) {
.toThrowError(/Can't bind to 'xlink:href'/); .toThrowError(/Can't bind to 'xlink:href'/);
}); });
it('should escape unsafe HTML values', () => { fixmeIvy('unknown') && it('should escape unsafe HTML values', () => {
const template = `<div [innerHTML]="ctxProp">Text</div>`; const template = `<div [innerHTML]="ctxProp">Text</div>`;
TestBed.overrideComponent(SecuredComponent, {set: {template}}); TestBed.overrideComponent(SecuredComponent, {set: {template}});
const fixture = TestBed.createComponent(SecuredComponent); const fixture = TestBed.createComponent(SecuredComponent);

View File

@ -16,7 +16,7 @@ import {TestBed, fakeAsync, tick} from '@angular/core/testing';
import {fixmeIvy} from '@angular/private/testing'; import {fixmeIvy} from '@angular/private/testing';
{ {
fixmeIvy('unknown') && describe('jit source mapping', () => { describe('jit source mapping', () => {
let jitSpy: jasmine.Spy; let jitSpy: jasmine.Spy;
let resourceLoader: MockResourceLoader; let resourceLoader: MockResourceLoader;
@ -102,160 +102,167 @@ import {fixmeIvy} from '@angular/private/testing';
function declareTests( function declareTests(
{ngUrl, templateDecorator}: {ngUrl, templateDecorator}:
{ngUrl: string, templateDecorator: (template: string) => { [key: string]: any }}) { {ngUrl: string, templateDecorator: (template: string) => { [key: string]: any }}) {
it('should use the right source url in html parse errors', fakeAsync(() => { fixmeIvy('unknown') &&
@Component({...templateDecorator('<div>\n </error>')}) it('should use the right source url in html parse errors', fakeAsync(() => {
class MyComp { @Component({...templateDecorator('<div>\n </error>')})
} class MyComp {
expect(() => compileAndCreateComponent(MyComp))
.toThrowError(
new RegExp(`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:2`));
}));
it('should use the right source url in template parse errors', fakeAsync(() => {
@Component({...templateDecorator('<div>\n <div unknown="{{ctxProp}}"></div>')})
class MyComp {
}
expect(() => compileAndCreateComponent(MyComp))
.toThrowError(
new RegExp(`Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:7`));
}));
it('should create a sourceMap for templates', fakeAsync(() => {
const template = `Hello World!`;
@Component({...templateDecorator(template)})
class MyComp {
}
compileAndCreateComponent(MyComp);
const sourceMap = getSourceMap('ng:///DynamicTestModule/MyComp.ngfactory.js');
expect(sourceMap.sources).toEqual([
'ng:///DynamicTestModule/MyComp.ngfactory.js', ngUrl
]);
expect(sourceMap.sourcesContent).toEqual([' ', template]);
}));
it('should report source location for di errors', fakeAsync(() => {
const template = `<div>\n <div someDir></div></div>`;
@Component({...templateDecorator(template)})
class MyComp {
}
@Directive({selector: '[someDir]'})
class SomeDir {
constructor() { throw new Error('Test'); }
}
TestBed.configureTestingModule({declarations: [SomeDir]});
let error: any;
try {
compileAndCreateComponent(MyComp);
} catch (e) {
error = e;
}
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
}));
it('should report di errors with multiple elements and directives', fakeAsync(() => {
const template = `<div someDir></div><div someDir="throw"></div>`;
@Component({...templateDecorator(template)})
class MyComp {
}
@Directive({selector: '[someDir]'})
class SomeDir {
constructor(@Attribute('someDir') someDir: string) {
if (someDir === 'throw') {
throw new Error('Test');
} }
}
}
TestBed.configureTestingModule({declarations: [SomeDir]}); expect(() => compileAndCreateComponent(MyComp))
let error: any; .toThrowError(new RegExp(
try { `Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:2`));
compileAndCreateComponent(MyComp); }));
} catch (e) {
error = e;
}
// The error should be logged from the 2nd-element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 1,
column: 19,
source: ngUrl,
});
}));
it('should report source location for binding errors', fakeAsync(() => { fixmeIvy('unknown') &&
const template = `<div>\n <span [title]="createError()"></span></div>`; it('should use the right source url in template parse errors', fakeAsync(() => {
@Component({...templateDecorator('<div>\n <div unknown="{{ctxProp}}"></div>')})
class MyComp {
}
@Component({...templateDecorator(template)}) expect(() => compileAndCreateComponent(MyComp))
class MyComp { .toThrowError(new RegExp(
createError() { throw new Error('Test'); } `Template parse errors[\\s\\S]*${ngUrl.replace('$', '\\$')}@1:7`));
} }));
const comp = compileAndCreateComponent(MyComp); fixmeIvy('unknown') && it('should create a sourceMap for templates', fakeAsync(() => {
const template = `Hello World!`;
let error: any; @Component({...templateDecorator(template)})
try { class MyComp {
comp.detectChanges(); }
} catch (e) {
error = e;
}
// the stack should point to the binding
expect(getSourcePositionForStack(error.stack)).toEqual({
line: 2,
column: 12,
source: ngUrl,
});
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
}));
it('should report source location for event errors', fakeAsync(() => { compileAndCreateComponent(MyComp);
const template = `<div>\n <span (click)="createError()"></span></div>`;
@Component({...templateDecorator(template)}) const sourceMap =
class MyComp { getSourceMap('ng:///DynamicTestModule/MyComp.ngfactory.js');
createError() { throw new Error('Test'); } expect(sourceMap.sources).toEqual([
} 'ng:///DynamicTestModule/MyComp.ngfactory.js', ngUrl
]);
expect(sourceMap.sourcesContent).toEqual([' ', template]);
}));
const comp = compileAndCreateComponent(MyComp);
let error: any; fixmeIvy('unknown') &&
const errorHandler = TestBed.get(ErrorHandler); it('should report source location for di errors', fakeAsync(() => {
spyOn(errorHandler, 'handleError').and.callFake((e: any) => error = e); const template = `<div>\n <div someDir></div></div>`;
comp.debugElement.children[0].children[0].triggerEventHandler('click', 'EVENT');
expect(error).toBeTruthy();
// the stack should point to the binding
expect(getSourcePositionForStack(error.stack)).toEqual({
line: 2,
column: 12,
source: ngUrl,
});
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
})); @Component({...templateDecorator(template)})
class MyComp {
}
@Directive({selector: '[someDir]'})
class SomeDir {
constructor() { throw new Error('Test'); }
}
TestBed.configureTestingModule({declarations: [SomeDir]});
let error: any;
try {
compileAndCreateComponent(MyComp);
} catch (e) {
error = e;
}
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
}));
fixmeIvy('unknown') &&
it('should report di errors with multiple elements and directives', fakeAsync(() => {
const template = `<div someDir></div><div someDir="throw"></div>`;
@Component({...templateDecorator(template)})
class MyComp {
}
@Directive({selector: '[someDir]'})
class SomeDir {
constructor(@Attribute('someDir') someDir: string) {
if (someDir === 'throw') {
throw new Error('Test');
}
}
}
TestBed.configureTestingModule({declarations: [SomeDir]});
let error: any;
try {
compileAndCreateComponent(MyComp);
} catch (e) {
error = e;
}
// The error should be logged from the 2nd-element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 1,
column: 19,
source: ngUrl,
});
}));
fixmeIvy('unknown') &&
it('should report source location for binding errors', fakeAsync(() => {
const template = `<div>\n <span [title]="createError()"></span></div>`;
@Component({...templateDecorator(template)})
class MyComp {
createError() { throw new Error('Test'); }
}
const comp = compileAndCreateComponent(MyComp);
let error: any;
try {
comp.detectChanges();
} catch (e) {
error = e;
}
// the stack should point to the binding
expect(getSourcePositionForStack(error.stack)).toEqual({
line: 2,
column: 12,
source: ngUrl,
});
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
}));
fixmeIvy('unknown') &&
it('should report source location for event errors', fakeAsync(() => {
const template = `<div>\n <span (click)="createError()"></span></div>`;
@Component({...templateDecorator(template)})
class MyComp {
createError() { throw new Error('Test'); }
}
const comp = compileAndCreateComponent(MyComp);
let error: any;
const errorHandler = TestBed.get(ErrorHandler);
spyOn(errorHandler, 'handleError').and.callFake((e: any) => error = e);
comp.debugElement.children[0].children[0].triggerEventHandler('click', 'EVENT');
expect(error).toBeTruthy();
// the stack should point to the binding
expect(getSourcePositionForStack(error.stack)).toEqual({
line: 2,
column: 12,
source: ngUrl,
});
// The error should be logged from the element
expect(getSourcePositionForStack(getErrorLoggerStack(error))).toEqual({
line: 2,
column: 4,
source: ngUrl,
});
}));
} }
}); });
} }

View File

@ -1564,7 +1564,7 @@ describe('ViewContainerRef', () => {
}); });
}); });
fixmeIvy(`Hooks don't run`) && describe('life cycle hooks', () => { describe('life cycle hooks', () => {
// Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
const log: string[] = []; const log: string[] = [];
@ -1608,206 +1608,216 @@ describe('ViewContainerRef', () => {
}); });
} }
it('should call all hooks in correct order when creating with createEmbeddedView', () => { fixmeIvy(`Hooks don't run`) &&
function SomeComponent_Template_0(rf: RenderFlags, ctx: any) { it('should call all hooks in correct order when creating with createEmbeddedView', () => {
if (rf & RenderFlags.Create) { function SomeComponent_Template_0(rf: RenderFlags, ctx: any) {
element(0, 'hooks'); if (rf & RenderFlags.Create) {
} element(0, 'hooks');
if (rf & RenderFlags.Update) { }
elementProperty(0, 'name', bind('C')); if (rf & RenderFlags.Update) {
} elementProperty(0, 'name', bind('C'));
} }
}
@Component({ @Component({
template: ` template: `
<ng-template #foo> <ng-template #foo>
<hooks [name]="'C'"></hooks> <hooks [name]="'C'"></hooks>
</ng-template> </ng-template>
<hooks vcref [tplRef]="foo" [name]="'A'"></hooks> <hooks vcref [tplRef]="foo" [name]="'A'"></hooks>
<hooks [name]="'B'"></hooks> <hooks [name]="'B'"></hooks>
` `
}) })
class SomeComponent { class SomeComponent {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: SomeComponent, type: SomeComponent,
selectors: [['some-comp']], selectors: [['some-comp']],
factory: () => new SomeComponent(), factory: () => new SomeComponent(),
consts: 4, consts: 4,
vars: 3, vars: 3,
template: (rf: RenderFlags, cmp: SomeComponent) => { template: (rf: RenderFlags, cmp: SomeComponent) => {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
template( template(
0, SomeComponent_Template_0, 1, 1, null, [], ['foo', ''], templateRefExtractor); 0, SomeComponent_Template_0, 1, 1, null, [], ['foo', ''],
element(2, 'hooks', ['vcref', '']); templateRefExtractor);
element(3, 'hooks'); element(2, 'hooks', ['vcref', '']);
} element(3, 'hooks');
if (rf & RenderFlags.Update) { }
const tplRef = reference(1); if (rf & RenderFlags.Update) {
elementProperty(2, 'tplRef', bind(tplRef)); const tplRef = reference(1);
elementProperty(2, 'name', bind('A')); elementProperty(2, 'tplRef', bind(tplRef));
elementProperty(3, 'name', bind('B')); elementProperty(2, 'name', bind('A'));
} elementProperty(3, 'name', bind('B'));
}, }
directives: [ComponentWithHooks, DirectiveWithVCRef] },
directives: [ComponentWithHooks, DirectiveWithVCRef]
});
}
log.length = 0;
const fixture = new ComponentFixture(SomeComponent);
expect(log).toEqual([
'onChanges-A', 'onInit-A', 'doCheck-A', 'onChanges-B', 'onInit-B', 'doCheck-B',
'afterContentInit-A', 'afterContentChecked-A', 'afterContentInit-B',
'afterContentChecked-B', 'afterViewInit-A', 'afterViewChecked-A', 'afterViewInit-B',
'afterViewChecked-B'
]);
log.length = 0;
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
directiveInstance !.vcref.createEmbeddedView(
directiveInstance !.tplRef, fixture.component);
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks></hooks><hooks>B</hooks>');
expect(log).toEqual([]);
log.length = 0;
fixture.update();
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks>C</hooks><hooks>B</hooks>');
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'onChanges-C', 'onInit-C', 'doCheck-C', 'afterContentInit-C',
'afterContentChecked-C', 'afterViewInit-C', 'afterViewChecked-C',
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
'afterViewChecked-B'
]);
log.length = 0;
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'doCheck-C', 'afterContentChecked-C', 'afterViewChecked-C',
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
'afterViewChecked-B'
]);
log.length = 0;
const viewRef = directiveInstance !.vcref.detach(0);
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
directiveInstance !.vcref.insert(viewRef !);
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'doCheck-C', 'afterContentChecked-C', 'afterViewChecked-C',
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
'afterViewChecked-B'
]);
log.length = 0;
directiveInstance !.vcref.remove(0);
fixture.update();
expect(log).toEqual([
'onDestroy-C', 'doCheck-A', 'doCheck-B', 'afterContentChecked-A',
'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
]);
}); });
}
log.length = 0; fixmeIvy(`Hooks don't run`) &&
it('should call all hooks in correct order when creating with createComponent', () => {
const fixture = new ComponentFixture(SomeComponent); @Component({
expect(log).toEqual([ template: `
'onChanges-A', 'onInit-A', 'doCheck-A', 'onChanges-B', 'onInit-B', 'doCheck-B',
'afterContentInit-A', 'afterContentChecked-A', 'afterContentInit-B',
'afterContentChecked-B', 'afterViewInit-A', 'afterViewChecked-A', 'afterViewInit-B',
'afterViewChecked-B'
]);
log.length = 0;
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
directiveInstance !.vcref.createEmbeddedView(directiveInstance !.tplRef, fixture.component);
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks></hooks><hooks>B</hooks>');
expect(log).toEqual([]);
log.length = 0;
fixture.update();
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks>C</hooks><hooks>B</hooks>');
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'onChanges-C', 'onInit-C', 'doCheck-C', 'afterContentInit-C',
'afterContentChecked-C', 'afterViewInit-C', 'afterViewChecked-C', 'afterContentChecked-A',
'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'doCheck-C', 'afterContentChecked-C', 'afterViewChecked-C',
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
const viewRef = directiveInstance !.vcref.detach(0);
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
directiveInstance !.vcref.insert(viewRef !);
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'doCheck-C', 'afterContentChecked-C', 'afterViewChecked-C',
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
directiveInstance !.vcref.remove(0);
fixture.update();
expect(log).toEqual([
'onDestroy-C', 'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
'afterViewChecked-A', 'afterViewChecked-B'
]);
});
it('should call all hooks in correct order when creating with createComponent', () => {
@Component({
template: `
<hooks vcref [name]="'A'"></hooks> <hooks vcref [name]="'A'"></hooks>
<hooks [name]="'B'"></hooks> <hooks [name]="'B'"></hooks>
` `
}) })
class SomeComponent { class SomeComponent {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: SomeComponent, type: SomeComponent,
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
selectors: [['some-comp']], selectors: [['some-comp']],
factory: () => new SomeComponent(), factory: () => new SomeComponent(),
consts: 2, consts: 2,
vars: 2, vars: 2,
template: (rf: RenderFlags, cmp: SomeComponent) => { template: (rf: RenderFlags, cmp: SomeComponent) => {
if (rf & RenderFlags.Create) { if (rf & RenderFlags.Create) {
element(0, 'hooks', ['vcref', '']); element(0, 'hooks', ['vcref', '']);
element(1, 'hooks'); element(1, 'hooks');
} }
if (rf & RenderFlags.Update) { if (rf & RenderFlags.Update) {
elementProperty(0, 'name', bind('A')); elementProperty(0, 'name', bind('A'));
elementProperty(1, 'name', bind('B')); elementProperty(1, 'name', bind('B'));
} }
}, },
directives: [ComponentWithHooks, DirectiveWithVCRef] directives: [ComponentWithHooks, DirectiveWithVCRef]
});
}
log.length = 0;
const fixture = new ComponentFixture(SomeComponent);
expect(log).toEqual([
'onChanges-A', 'onInit-A', 'doCheck-A', 'onChanges-B', 'onInit-B', 'doCheck-B',
'afterContentInit-A', 'afterContentChecked-A', 'afterContentInit-B',
'afterContentChecked-B', 'afterViewInit-A', 'afterViewChecked-A', 'afterViewInit-B',
'afterViewChecked-B'
]);
log.length = 0;
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
const componentRef = directiveInstance !.vcref.createComponent(
directiveInstance !.cfr.resolveComponentFactory(ComponentWithHooks));
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks></hooks><hooks>B</hooks>');
expect(log).toEqual([]);
componentRef.instance.name = 'D';
log.length = 0;
fixture.update();
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks>D</hooks><hooks>B</hooks>');
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'onChanges-D', 'onInit-D', 'doCheck-D', 'afterContentInit-D',
'afterContentChecked-D', 'afterViewInit-D', 'afterViewChecked-D',
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
'afterViewChecked-B'
]);
log.length = 0;
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'doCheck-D', 'afterContentChecked-D', 'afterViewChecked-D',
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
'afterViewChecked-B'
]);
log.length = 0;
const viewRef = directiveInstance !.vcref.detach(0);
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
directiveInstance !.vcref.insert(viewRef !);
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'doCheck-D', 'afterContentChecked-D', 'afterViewChecked-D',
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A',
'afterViewChecked-B'
]);
log.length = 0;
directiveInstance !.vcref.remove(0);
fixture.update();
expect(log).toEqual([
'onDestroy-D', 'doCheck-A', 'doCheck-B', 'afterContentChecked-A',
'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
]);
}); });
}
log.length = 0;
const fixture = new ComponentFixture(SomeComponent);
expect(log).toEqual([
'onChanges-A', 'onInit-A', 'doCheck-A', 'onChanges-B', 'onInit-B', 'doCheck-B',
'afterContentInit-A', 'afterContentChecked-A', 'afterContentInit-B',
'afterContentChecked-B', 'afterViewInit-A', 'afterViewChecked-A', 'afterViewInit-B',
'afterViewChecked-B'
]);
log.length = 0;
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
const componentRef = directiveInstance !.vcref.createComponent(
directiveInstance !.cfr.resolveComponentFactory(ComponentWithHooks));
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks></hooks><hooks>B</hooks>');
expect(log).toEqual([]);
componentRef.instance.name = 'D';
log.length = 0;
fixture.update();
expect(fixture.html).toEqual('<hooks vcref="">A</hooks><hooks>D</hooks><hooks>B</hooks>');
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'onChanges-D', 'onInit-D', 'doCheck-D', 'afterContentInit-D',
'afterContentChecked-D', 'afterViewInit-D', 'afterViewChecked-D', 'afterContentChecked-A',
'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'doCheck-D', 'afterContentChecked-D', 'afterViewChecked-D',
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
const viewRef = directiveInstance !.vcref.detach(0);
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
directiveInstance !.vcref.insert(viewRef !);
fixture.update();
expect(log).toEqual([
'doCheck-A', 'doCheck-B', 'doCheck-D', 'afterContentChecked-D', 'afterViewChecked-D',
'afterContentChecked-A', 'afterContentChecked-B', 'afterViewChecked-A', 'afterViewChecked-B'
]);
log.length = 0;
directiveInstance !.vcref.remove(0);
fixture.update();
expect(log).toEqual([
'onDestroy-D', 'doCheck-A', 'doCheck-B', 'afterContentChecked-A', 'afterContentChecked-B',
'afterViewChecked-A', 'afterViewChecked-B'
]);
});
}); });
describe('host bindings', () => { describe('host bindings', () => {

View File

@ -114,10 +114,10 @@ import {fixmeIvy} from '@angular/private/testing';
expect(debugCtx.nodeIndex).toBe(1); expect(debugCtx.nodeIndex).toBe(1);
}); });
fixmeIvy('unknown') && describe('deps', () => { describe('deps', () => {
class Dep {} class Dep {}
it('should inject deps from the same element', () => { fixmeIvy('unknown') && it('should inject deps from the same element', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([
elementDef(0, NodeFlags.None, null, null, 2, 'span'), elementDef(0, NodeFlags.None, null, null, 2, 'span'),
directiveDef(1, NodeFlags.None, null, 0, Dep, []), directiveDef(1, NodeFlags.None, null, 0, Dep, []),
@ -127,7 +127,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep instanceof Dep).toBeTruthy(); expect(instance.dep instanceof Dep).toBeTruthy();
}); });
it('should inject deps from a parent element', () => { fixmeIvy('unknown') && it('should inject deps from a parent element', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([
elementDef(0, NodeFlags.None, null, null, 3, 'span'), elementDef(0, NodeFlags.None, null, null, 3, 'span'),
directiveDef(1, NodeFlags.None, null, 0, Dep, []), directiveDef(1, NodeFlags.None, null, 0, Dep, []),
@ -138,7 +138,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep instanceof Dep).toBeTruthy(); expect(instance.dep instanceof Dep).toBeTruthy();
}); });
it('should not inject deps from sibling root elements', () => { fixmeIvy('unknown') && it('should not inject deps from sibling root elements', () => {
const rootElNodes = [ const rootElNodes = [
elementDef(0, NodeFlags.None, null, null, 1, 'span'), elementDef(0, NodeFlags.None, null, null, 1, 'span'),
directiveDef(1, NodeFlags.None, null, 0, Dep, []), directiveDef(1, NodeFlags.None, null, 0, Dep, []),
@ -167,7 +167,7 @@ import {fixmeIvy} from '@angular/private/testing';
' NullInjectorError: No provider for Dep!'); ' NullInjectorError: No provider for Dep!');
}); });
it('should inject from a parent element in a parent view', () => { fixmeIvy('unknown') && it('should inject from a parent element in a parent view', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([
elementDef( elementDef(
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null, 0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
@ -181,7 +181,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep instanceof Dep).toBeTruthy(); expect(instance.dep instanceof Dep).toBeTruthy();
}); });
it('should throw for missing dependencies', () => { fixmeIvy('unknown') && it('should throw for missing dependencies', () => {
expect(() => createAndGetRootNodes(compViewDef([ expect(() => createAndGetRootNodes(compViewDef([
elementDef(0, NodeFlags.None, null, null, 1, 'span'), elementDef(0, NodeFlags.None, null, null, 1, 'span'),
directiveDef(1, NodeFlags.None, null, 0, SomeService, ['nonExistingDep']) directiveDef(1, NodeFlags.None, null, 0, SomeService, ['nonExistingDep'])
@ -192,7 +192,7 @@ import {fixmeIvy} from '@angular/private/testing';
' NullInjectorError: No provider for nonExistingDep!'); ' NullInjectorError: No provider for nonExistingDep!');
}); });
it('should use null for optional missing dependencies', () => { fixmeIvy('unknown') && it('should use null for optional missing dependencies', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([
elementDef(0, NodeFlags.None, null, null, 1, 'span'), elementDef(0, NodeFlags.None, null, null, 1, 'span'),
directiveDef( directiveDef(
@ -202,7 +202,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep).toBe(null); expect(instance.dep).toBe(null);
}); });
it('should skip the current element when using SkipSelf', () => { fixmeIvy('unknown') && it('should skip the current element when using SkipSelf', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([
elementDef(0, NodeFlags.None, null, null, 4, 'span'), elementDef(0, NodeFlags.None, null, null, 4, 'span'),
providerDef(NodeFlags.TypeValueProvider, null, 'someToken', 'someParentValue', []), providerDef(NodeFlags.TypeValueProvider, null, 'someToken', 'someParentValue', []),
@ -214,18 +214,19 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep).toBe('someParentValue'); expect(instance.dep).toBe('someParentValue');
}); });
it('should ask the root injector', fixmeIvy('unknown') &&
withModule({providers: [{provide: 'rootDep', useValue: 'rootValue'}]}, () => { it('should ask the root injector',
createAndGetRootNodes(compViewDef([ withModule({providers: [{provide: 'rootDep', useValue: 'rootValue'}]}, () => {
elementDef(0, NodeFlags.None, null, null, 1, 'span'), createAndGetRootNodes(compViewDef([
directiveDef(1, NodeFlags.None, null, 0, SomeService, ['rootDep']) elementDef(0, NodeFlags.None, null, null, 1, 'span'),
])); directiveDef(1, NodeFlags.None, null, 0, SomeService, ['rootDep'])
]));
expect(instance.dep).toBe('rootValue'); expect(instance.dep).toBe('rootValue');
})); }));
describe('builtin tokens', () => { describe('builtin tokens', () => {
it('should inject ViewContainerRef', () => { fixmeIvy('unknown') && it('should inject ViewContainerRef', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([
anchorDef(NodeFlags.EmbeddedViews, null, null, 1), anchorDef(NodeFlags.EmbeddedViews, null, null, 1),
directiveDef(1, NodeFlags.None, null, 0, SomeService, [ViewContainerRef]), directiveDef(1, NodeFlags.None, null, 0, SomeService, [ViewContainerRef]),
@ -234,7 +235,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep.createEmbeddedView).toBeTruthy(); expect(instance.dep.createEmbeddedView).toBeTruthy();
}); });
it('should inject TemplateRef', () => { fixmeIvy('unknown') && it('should inject TemplateRef', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([
anchorDef(NodeFlags.None, null, null, 1, null, compViewDefFactory([anchorDef( anchorDef(NodeFlags.None, null, null, 1, null, compViewDefFactory([anchorDef(
NodeFlags.None, null, null, 0)])), NodeFlags.None, null, null, 0)])),
@ -244,7 +245,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep.createEmbeddedView).toBeTruthy(); expect(instance.dep.createEmbeddedView).toBeTruthy();
}); });
it('should inject ElementRef', () => { fixmeIvy('unknown') && it('should inject ElementRef', () => {
const {view} = createAndGetRootNodes(compViewDef([ const {view} = createAndGetRootNodes(compViewDef([
elementDef(0, NodeFlags.None, null, null, 1, 'span'), elementDef(0, NodeFlags.None, null, null, 1, 'span'),
directiveDef(1, NodeFlags.None, null, 0, SomeService, [ElementRef]), directiveDef(1, NodeFlags.None, null, 0, SomeService, [ElementRef]),
@ -253,7 +254,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep.nativeElement).toBe(asElementData(view, 0).renderElement); expect(instance.dep.nativeElement).toBe(asElementData(view, 0).renderElement);
}); });
it('should inject Injector', () => { fixmeIvy('unknown') && it('should inject Injector', () => {
const {view} = createAndGetRootNodes(compViewDef([ const {view} = createAndGetRootNodes(compViewDef([
elementDef(0, NodeFlags.None, null, null, 1, 'span'), elementDef(0, NodeFlags.None, null, null, 1, 'span'),
directiveDef(1, NodeFlags.None, null, 0, SomeService, [Injector]), directiveDef(1, NodeFlags.None, null, 0, SomeService, [Injector]),
@ -262,30 +263,32 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep.get(SomeService)).toBe(instance); expect(instance.dep.get(SomeService)).toBe(instance);
}); });
it('should inject ChangeDetectorRef for non component providers', () => { fixmeIvy('unknown') &&
const {view} = createAndGetRootNodes(compViewDef([ it('should inject ChangeDetectorRef for non component providers', () => {
elementDef(0, NodeFlags.None, null, null, 1, 'span'), const {view} = createAndGetRootNodes(compViewDef([
directiveDef(1, NodeFlags.None, null, 0, SomeService, [ChangeDetectorRef]) elementDef(0, NodeFlags.None, null, null, 1, 'span'),
])); directiveDef(1, NodeFlags.None, null, 0, SomeService, [ChangeDetectorRef])
]));
expect(instance.dep._view).toBe(view); expect(instance.dep._view).toBe(view);
}); });
it('should inject ChangeDetectorRef for component providers', () => { fixmeIvy('unknown') &&
const {view, rootNodes} = createAndGetRootNodes(compViewDef([ it('should inject ChangeDetectorRef for component providers', () => {
elementDef( const {view, rootNodes} = createAndGetRootNodes(compViewDef([
0, NodeFlags.None, null, null, 1, 'div', null, null, null, null, elementDef(
() => compViewDef([ 0, NodeFlags.None, null, null, 1, 'div', null, null, null, null,
elementDef(0, NodeFlags.None, null, null, 0, 'span'), () => compViewDef([
])), elementDef(0, NodeFlags.None, null, null, 0, 'span'),
directiveDef(1, NodeFlags.Component, null, 0, SomeService, [ChangeDetectorRef]), ])),
])); directiveDef(1, NodeFlags.Component, null, 0, SomeService, [ChangeDetectorRef]),
]));
const compView = asElementData(view, 0).componentView; const compView = asElementData(view, 0).componentView;
expect(instance.dep._view).toBe(compView); expect(instance.dep._view).toBe(compView);
}); });
it('should inject RendererV1', () => { fixmeIvy('unknown') && it('should inject RendererV1', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([
elementDef( elementDef(
0, NodeFlags.None, null, null, 1, 'span', null, null, null, null, 0, NodeFlags.None, null, null, 1, 'span', null, null, null, null,
@ -296,7 +299,7 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep.createElement).toBeTruthy(); expect(instance.dep.createElement).toBeTruthy();
}); });
it('should inject Renderer2', () => { fixmeIvy('unknown') && it('should inject Renderer2', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([
elementDef( elementDef(
0, NodeFlags.None, null, null, 1, 'span', null, null, null, null, 0, NodeFlags.None, null, null, 1, 'span', null, null, null, null,