test(ivy): run browser-specific @angular/core tests on CI (#27545)
PR Close #27545
This commit is contained in:
parent
aa48810d80
commit
5657126d86
@ -66,9 +66,6 @@ jasmine_node_test(
|
||||
|
||||
ts_web_test_suite(
|
||||
name = "test_web",
|
||||
tags = [
|
||||
"fixme-ivy-aot",
|
||||
],
|
||||
deps = [
|
||||
":test_lib",
|
||||
],
|
||||
|
@ -5,15 +5,15 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {AUTO_STYLE, AnimationEvent, AnimationOptions, AnimationPlayer, NoopAnimationPlayer, animate, animateChild, group, keyframes, query, state, style, transition, trigger, ɵPRE_STYLE as PRE_STYLE} from '@angular/animations';
|
||||
import {AUTO_STYLE, AnimationEvent, AnimationOptions, animate, animateChild, group, keyframes, query, state, style, transition, trigger, ɵPRE_STYLE as PRE_STYLE} from '@angular/animations';
|
||||
import {AnimationDriver, ɵAnimationEngine, ɵNoopAnimationDriver as NoopAnimationDriver} from '@angular/animations/browser';
|
||||
import {MockAnimationDriver, MockAnimationPlayer} from '@angular/animations/browser/testing';
|
||||
import {ChangeDetectorRef, Component, HostBinding, HostListener, Inject, RendererFactory2, ViewChild} from '@angular/core';
|
||||
import {TestBed, fakeAsync, flushMicrotasks} from '@angular/core/testing';
|
||||
import {ɵDomRendererFactory2} from '@angular/platform-browser';
|
||||
import {ANIMATION_MODULE_TYPE, BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
import {TestBed, fakeAsync, flushMicrotasks} from '../../testing';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
|
||||
const DEFAULT_NAMESPACE_ID = 'id';
|
||||
const DEFAULT_COMPONENT_ID = '1';
|
||||
@ -66,7 +66,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
}
|
||||
|
||||
describe('fakeAsync testing', () => {
|
||||
it('should only require one flushMicrotasks call to kick off animation callbacks',
|
||||
fixmeIvy('unknown').it(
|
||||
'should only require one flushMicrotasks call to kick off animation callbacks',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'cmp',
|
||||
@ -109,7 +110,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(cmp.status).toEqual('done');
|
||||
}));
|
||||
|
||||
it('should always run .start callbacks before .done callbacks even for noop animations',
|
||||
fixmeIvy('unknown').it(
|
||||
'should always run .start callbacks before .done callbacks even for noop animations',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'cmp',
|
||||
@ -141,7 +143,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(cmp.log).toEqual(['start', 'done']);
|
||||
}));
|
||||
|
||||
it('should emit the correct totalTime value for a noop-animation', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should emit the correct totalTime value for a noop-animation', fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'cmp',
|
||||
template: `
|
||||
@ -297,7 +300,7 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
});
|
||||
|
||||
describe('animation triggers', () => {
|
||||
it('should trigger a state change animation from void => state', () => {
|
||||
fixmeIvy('unknown').it('should trigger a state change animation from void => state', () => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
template: `
|
||||
@ -327,7 +330,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
]);
|
||||
});
|
||||
|
||||
it('should allow a transition to use a function to determine what method to run', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should allow a transition to use a function to determine what method to run', () => {
|
||||
let valueToMatch = '';
|
||||
let capturedElement: any;
|
||||
const transitionFn = (fromState: string, toState: string, element: any) => {
|
||||
@ -339,9 +343,10 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
selector: 'if-cmp',
|
||||
template: '<div #element [@myAnimation]="exp"></div>',
|
||||
animations: [
|
||||
trigger('myAnimation', [transition(
|
||||
transitionFn,
|
||||
[style({opacity: 0}), animate(1234, style({opacity: 1}))])]),
|
||||
trigger(
|
||||
'myAnimation',
|
||||
[transition(
|
||||
transitionFn, [style({opacity: 0}), animate(1234, style({opacity: 1}))])]),
|
||||
]
|
||||
})
|
||||
class Cmp {
|
||||
@ -373,12 +378,12 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(players.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should allow a transition to use a function to determine what method to run and expose any parameter values',
|
||||
fixmeIvy('unknown').it(
|
||||
'should allow a transition to use a function to determine what method to run and expose any parameter values',
|
||||
() => {
|
||||
const transitionFn =
|
||||
(fromState: string, toState: string, element: any, params: {[key: string]: any}) => {
|
||||
return params['doMatch'] == true;
|
||||
};
|
||||
(fromState: string, toState: string, element: any,
|
||||
params: {[key: string]: any}) => { return params['doMatch'] == true; };
|
||||
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
@ -454,7 +459,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(player.duration).toEqual(1234);
|
||||
});
|
||||
|
||||
it('should always cancel the previous transition if a follow-up transition is not matched',
|
||||
fixmeIvy('unknown').it(
|
||||
'should always cancel the previous transition if a follow-up transition is not matched',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
@ -464,7 +470,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
animations: [trigger(
|
||||
'myAnimation',
|
||||
[transition(
|
||||
'a => b', [style({'opacity': '0'}), animate(500, style({'opacity': '1'}))])])],
|
||||
'a => b',
|
||||
[style({'opacity': '0'}), animate(500, style({'opacity': '1'}))])])],
|
||||
})
|
||||
class Cmp {
|
||||
exp: any;
|
||||
@ -533,7 +540,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(completed).toBe(true);
|
||||
}));
|
||||
|
||||
it('should always fire inner callbacks even if no animation is fired when a view is inserted',
|
||||
fixmeIvy('unknown').it(
|
||||
'should always fire inner callbacks even if no animation is fired when a view is inserted',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
@ -569,7 +577,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(cmp.log).toEqual(['myAnimation-start', 'myAnimation-done']);
|
||||
}));
|
||||
|
||||
it('should only turn a view removal as into `void` state transition', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should only turn a view removal as into `void` state transition', () => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
template: `
|
||||
@ -579,9 +588,11 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
'myAnimation',
|
||||
[
|
||||
transition(
|
||||
'void <=> *', [style({width: '0px'}), animate(1000, style({width: '100px'}))]),
|
||||
'void <=> *',
|
||||
[style({width: '0px'}), animate(1000, style({width: '100px'}))]),
|
||||
transition(
|
||||
'* => *', [style({height: '0px'}), animate(1000, style({height: '100px'}))]),
|
||||
'* => *',
|
||||
[style({height: '0px'}), animate(1000, style({height: '100px'}))]),
|
||||
])]
|
||||
})
|
||||
class Cmp {
|
||||
@ -664,7 +675,7 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
]);
|
||||
});
|
||||
|
||||
it('should stringify boolean triggers to `1` and `0`', () => {
|
||||
fixmeIvy('unknown').it('should stringify boolean triggers to `1` and `0`', () => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
template: `
|
||||
@ -817,7 +828,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
});
|
||||
|
||||
describe('host bindings', () => {
|
||||
it('should trigger a state change animation from state => state on the component host element',
|
||||
fixmeIvy('unknown').it(
|
||||
'should trigger a state change animation from state => state on the component host element',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'my-cmp',
|
||||
@ -849,11 +861,14 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
|
||||
const data = getLog().pop() !;
|
||||
expect(data.element).toEqual(fixture.elementRef.nativeElement);
|
||||
expect(data.keyframes).toEqual([{offset: 0, opacity: '0'}, {offset: 1, opacity: '1'}]);
|
||||
expect(data.keyframes).toEqual([
|
||||
{offset: 0, opacity: '0'}, {offset: 1, opacity: '1'}
|
||||
]);
|
||||
}));
|
||||
|
||||
// nonAnimationRenderer => animationRenderer
|
||||
it('should trigger a leave animation when the inner components host binding updates',
|
||||
fixmeIvy('unknown').it(
|
||||
'should trigger a leave animation when the inner components host binding updates',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'parent-cmp',
|
||||
@ -955,7 +970,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
}));
|
||||
|
||||
// animationRenderer => animationRenderer
|
||||
it('should trigger a leave animation when both the inner and outer components trigger on the same element',
|
||||
fixmeIvy('unknown').it(
|
||||
'should trigger a leave animation when both the inner and outer components trigger on the same element',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'parent-cmp',
|
||||
@ -976,7 +992,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
selector: 'child-cmp',
|
||||
template: '...',
|
||||
animations: [trigger(
|
||||
'host', [transition(
|
||||
'host',
|
||||
[transition(
|
||||
':leave',
|
||||
[style({width: '100px'}), animate(1000, style({width: '0px'}))])])]
|
||||
})
|
||||
@ -1922,7 +1939,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(p.contains(c2)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should detect trigger changes based on object.value properties', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should detect trigger changes based on object.value properties', () => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
template: `
|
||||
@ -2006,7 +2024,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(players.length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should update the final state styles when params update even if the expression hasn\'t changed',
|
||||
fixmeIvy('unknown').it(
|
||||
'should update the final state styles when params update even if the expression hasn\'t changed',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
@ -2098,7 +2117,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
]);
|
||||
});
|
||||
|
||||
it('should retain substituted styles on the element once the animation is complete if referenced in the final state',
|
||||
fixmeIvy('unknown').it(
|
||||
'should retain substituted styles on the element once the animation is complete if referenced in the final state',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
@ -2443,7 +2463,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
});
|
||||
|
||||
describe('animation listeners', () => {
|
||||
it('should trigger a `start` state change listener for when the animation changes state from void => state',
|
||||
fixmeIvy('unknown').it(
|
||||
'should trigger a `start` state change listener for when the animation changes state from void => state',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
@ -2480,7 +2501,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(cmp.event.toState).toEqual('true');
|
||||
}));
|
||||
|
||||
it('should trigger a `done` state change listener for when the animation changes state from a => b',
|
||||
fixmeIvy('unknown').it(
|
||||
'should trigger a `done` state change listener for when the animation changes state from a => b',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
@ -2490,7 +2512,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
animations: [trigger(
|
||||
'myAnimation123',
|
||||
[transition(
|
||||
'* => b', [style({'opacity': '0'}), animate(999, style({'opacity': '1'}))])])],
|
||||
'* => b',
|
||||
[style({'opacity': '0'}), animate(999, style({'opacity': '1'}))])])],
|
||||
})
|
||||
class Cmp {
|
||||
exp: any = false;
|
||||
@ -2523,7 +2546,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(cmp.event.toState).toEqual('b');
|
||||
}));
|
||||
|
||||
it('should handle callbacks for multiple triggers running simultaneously', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should handle callbacks for multiple triggers running simultaneously', fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
template: `
|
||||
@ -2587,7 +2611,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(cmp.event2.triggerName).toBeTruthy('ani2');
|
||||
}));
|
||||
|
||||
it('should handle callbacks for multiple triggers running simultaneously on the same element',
|
||||
fixmeIvy('unknown').it(
|
||||
'should handle callbacks for multiple triggers running simultaneously on the same element',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
@ -2709,7 +2734,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(elm.innerText.trim()).toEqual('');
|
||||
}));
|
||||
|
||||
it('should trigger a state change listener for when the animation changes state from void => state on the host element',
|
||||
fixmeIvy('unknown').it(
|
||||
'should trigger a state change listener for when the animation changes state from void => state on the host element',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'my-cmp',
|
||||
@ -2747,7 +2773,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(cmp.event.toState).toEqual('TRUE');
|
||||
}));
|
||||
|
||||
it('should always fire callbacks even when a transition is not detected', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should always fire callbacks even when a transition is not detected', fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'my-cmp',
|
||||
template: `
|
||||
@ -2783,7 +2810,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(cmp.log).toEqual(['start => b', 'done => b']);
|
||||
}));
|
||||
|
||||
it('should fire callback events for leave animations even if there is no leave transition',
|
||||
fixmeIvy('unknown').it(
|
||||
'should fire callback events for leave animations even if there is no leave transition',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'my-cmp',
|
||||
@ -2823,7 +2851,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(cmp.log).toEqual(['start => void', 'done => void']);
|
||||
}));
|
||||
|
||||
it('should fire callbacks on a sub animation once it starts and finishes', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should fire callbacks on a sub animation once it starts and finishes', fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'my-cmp',
|
||||
template: `
|
||||
@ -2907,7 +2936,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(cmp.log).toEqual(['parent-done', 'child-done']);
|
||||
}));
|
||||
|
||||
it('should fire callbacks and collect the correct the totalTime and element details for any queried sub animations',
|
||||
fixmeIvy('unknown').it(
|
||||
'should fire callbacks and collect the correct the totalTime and element details for any queried sub animations',
|
||||
fakeAsync(
|
||||
() => {
|
||||
@Component({
|
||||
@ -3255,7 +3285,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(parent.childElementCount).toEqual(0);
|
||||
});
|
||||
|
||||
it('should properly resolve animation event listeners when disabled', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should properly resolve animation event listeners when disabled', fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
template: `
|
||||
@ -3360,7 +3391,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(getLog().length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should treat the property as true when the expression is missing', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should treat the property as true when the expression is missing', () => {
|
||||
@Component({
|
||||
selector: 'parent-cmp',
|
||||
animations: [
|
||||
@ -3397,7 +3429,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(getLog().length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should respect parent/sub animations when the respective area in the DOM is disabled',
|
||||
fixmeIvy('unknown').it(
|
||||
'should respect parent/sub animations when the respective area in the DOM is disabled',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'parent-cmp',
|
||||
@ -3569,7 +3602,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
/only state\(\) and transition\(\) definitions can sit inside of a trigger\(\)/);
|
||||
});
|
||||
|
||||
it('should combine multiple errors together into one exception when an animation fails to be built',
|
||||
fixmeIvy('unknown').it(
|
||||
'should combine multiple errors together into one exception when an animation fails to be built',
|
||||
() => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
@ -3658,7 +3692,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
expect(() => { TestBed.createComponent(Cmp); }).not.toThrowError();
|
||||
});
|
||||
|
||||
it('should continue to clean up DOM-related animation artificats even if a compiler-level error is thrown midway',
|
||||
fixmeIvy('unknown').it(
|
||||
'should continue to clean up DOM-related animation artificats even if a compiler-level error is thrown midway',
|
||||
() => {
|
||||
@Component({
|
||||
selector: 'if-cmp',
|
||||
@ -3711,7 +3746,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw when using an @prop binding without the animation module', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should throw when using an @prop binding without the animation module', () => {
|
||||
@Component({template: `<div [@myAnimation]="true"></div>`})
|
||||
class Cmp {
|
||||
}
|
||||
@ -3723,7 +3759,8 @@ const DEFAULT_COMPONENT_ID = '1';
|
||||
'Found the synthetic property @myAnimation. Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.');
|
||||
});
|
||||
|
||||
it('should throw when using an @prop listener without the animation module', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should throw when using an @prop listener without the animation module', () => {
|
||||
@Component({template: `<div (@myAnimation.start)="a = true"></div>`})
|
||||
class Cmp {
|
||||
a: any;
|
||||
|
@ -12,12 +12,11 @@ import {ENTER_CLASSNAME, LEAVE_CLASSNAME} from '@angular/animations/browser/src/
|
||||
import {MockAnimationDriver, MockAnimationPlayer} from '@angular/animations/browser/testing';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {Component, HostBinding, ViewChild} from '@angular/core';
|
||||
import {TestBed, fakeAsync, flushMicrotasks} from '@angular/core/testing';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
|
||||
import {HostListener} from '../../src/metadata/directives';
|
||||
import {TestBed} from '../../testing';
|
||||
import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
|
||||
|
||||
|
||||
(function() {
|
||||
// these tests are only mean't to be run within the DOM (for now)
|
||||
@ -296,7 +295,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
|
||||
expect(p6.element.classList.contains('b3')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should be able to query all active animations using :animating in a query', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should be able to query all active animations using :animating in a query', () => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
template: `
|
||||
@ -802,7 +802,7 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
|
||||
expect(player.element.style.height).toEqual('444px');
|
||||
});
|
||||
|
||||
it('should find newly inserted items in the component via :enter', () => {
|
||||
fixmeIvy('unknown').it('should find newly inserted items in the component via :enter', () => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
template: `
|
||||
@ -853,7 +853,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
|
||||
});
|
||||
});
|
||||
|
||||
it('should cleanup :enter and :leave artifacts from nodes when any animation sequences fail to be built',
|
||||
fixmeIvy('unknown').it(
|
||||
'should cleanup :enter and :leave artifacts from nodes when any animation sequences fail to be built',
|
||||
() => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
@ -2234,7 +2235,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
|
||||
expect(p3.element.classList.contains('parent1')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should emulate a leave animation on the nearest sub host elements when a parent is removed',
|
||||
fixmeIvy('unknown').it(
|
||||
'should emulate a leave animation on the nearest sub host elements when a parent is removed',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
@ -2438,7 +2440,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
|
||||
expect(element.innerText.trim()).toMatch(/this\s+child/mg);
|
||||
}));
|
||||
|
||||
it('should only mark outermost *directive nodes :enter and :leave when inserts and removals occur',
|
||||
fixmeIvy('unknown').it(
|
||||
'should only mark outermost *directive nodes :enter and :leave when inserts and removals occur',
|
||||
() => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
@ -2512,7 +2515,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
|
||||
expect(p4.element.classList.contains('d'));
|
||||
});
|
||||
|
||||
it('should collect multiple root levels of :enter and :leave nodes', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should collect multiple root levels of :enter and :leave nodes', () => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
animations: [
|
||||
@ -2631,7 +2635,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
|
||||
expect(p3.element.classList.contains('page2')).toBe(true);
|
||||
});
|
||||
|
||||
it('should emulate leave animation callbacks for all sub elements that have leave triggers within the component',
|
||||
fixmeIvy('unknown').it(
|
||||
'should emulate leave animation callbacks for all sub elements that have leave triggers within the component',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
@ -2732,7 +2737,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
|
||||
expect(engine.players[0].getRealPlayer()).toBe(players[1]);
|
||||
});
|
||||
|
||||
it('should fire and synchronize the start/done callbacks on sub triggers even if they are not allowed to animate within the animation',
|
||||
fixmeIvy('unknown').it(
|
||||
'should fire and synchronize the start/done callbacks on sub triggers even if they are not allowed to animate within the animation',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'parent-cmp',
|
||||
@ -2832,7 +2838,8 @@ import {fakeAsync, flushMicrotasks} from '../../testing/src/fake_async';
|
||||
expect(child.log).toEqual(['child-start', 'child-done']);
|
||||
}));
|
||||
|
||||
it('should fire and synchronize the start/done callbacks on multiple blocked sub triggers',
|
||||
fixmeIvy('unknown').it(
|
||||
'should fire and synchronize the start/done callbacks on multiple blocked sub triggers',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'cmp',
|
||||
|
@ -11,6 +11,7 @@ import {MockAnimationDriver, MockAnimationPlayer} from '@angular/animations/brow
|
||||
import {Component, HostBinding} from '@angular/core';
|
||||
import {TestBed, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
import {ActivatedRoute, Router, RouterOutlet} from '@angular/router';
|
||||
import {RouterTestingModule} from '@angular/router/testing';
|
||||
|
||||
@ -33,7 +34,8 @@ import {RouterTestingModule} from '@angular/router/testing';
|
||||
});
|
||||
});
|
||||
|
||||
it('should query the old and new routes via :leave and :enter', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should query the old and new routes via :leave and :enter', fakeAsync(() => {
|
||||
@Component({
|
||||
animations: [
|
||||
trigger(
|
||||
@ -150,7 +152,8 @@ import {RouterTestingModule} from '@angular/router/testing';
|
||||
]);
|
||||
}));
|
||||
|
||||
it('should allow inner enter animations to be emulated within a routed item', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should allow inner enter animations to be emulated within a routed item', fakeAsync(() => {
|
||||
@Component({
|
||||
animations: [
|
||||
trigger(
|
||||
@ -255,7 +258,8 @@ import {RouterTestingModule} from '@angular/router/testing';
|
||||
]);
|
||||
}));
|
||||
|
||||
it('should allow inner leave animations to be emulated within a routed item', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should allow inner leave animations to be emulated within a routed item', fakeAsync(() => {
|
||||
@Component({
|
||||
animations: [
|
||||
trigger(
|
||||
@ -301,7 +305,8 @@ import {RouterTestingModule} from '@angular/router/testing';
|
||||
]),
|
||||
trigger(
|
||||
'ifAnimation',
|
||||
[transition(':leave', [style({opacity: 1}), animate(1000, style({opacity: 0}))])]),
|
||||
[transition(
|
||||
':leave', [style({opacity: 1}), animate(1000, style({opacity: 0}))])]),
|
||||
]
|
||||
})
|
||||
class Page1Cmp {
|
||||
@ -359,7 +364,8 @@ import {RouterTestingModule} from '@angular/router/testing';
|
||||
]);
|
||||
}));
|
||||
|
||||
it('should properly collect :enter / :leave router nodes even when another non-router *template component is within the trigger boundaries',
|
||||
fixmeIvy('unknown').it(
|
||||
'should properly collect :enter / :leave router nodes even when another non-router *template component is within the trigger boundaries',
|
||||
fakeAsync(() => {
|
||||
@Component({
|
||||
selector: 'ani-cmp',
|
||||
@ -445,9 +451,11 @@ import {RouterTestingModule} from '@angular/router/testing';
|
||||
expect(ip2.element.innerText).toEqual('page2');
|
||||
}));
|
||||
|
||||
it('should allow a recursive set of :leave animations to occur for nested routes',
|
||||
fixmeIvy('unknown').it(
|
||||
'should allow a recursive set of :leave animations to occur for nested routes',
|
||||
fakeAsync(() => {
|
||||
@Component({selector: 'ani-cmp', template: '<router-outlet name="recur"></router-outlet>'})
|
||||
@Component(
|
||||
{selector: 'ani-cmp', template: '<router-outlet name="recur"></router-outlet>'})
|
||||
class ContainerCmp {
|
||||
constructor(private _router: Router) {}
|
||||
log: string[] = [];
|
||||
@ -464,7 +472,8 @@ import {RouterTestingModule} from '@angular/router/testing';
|
||||
trigger(
|
||||
'pageAnimations',
|
||||
[
|
||||
transition(':leave', [group([
|
||||
transition(
|
||||
':leave', [group([
|
||||
sequence([style({opacity: 1}), animate('1s', style({opacity: 0}))]),
|
||||
query('@*', animateChild(), {optional: true})
|
||||
])]),
|
||||
|
@ -5,15 +5,15 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {animate, group, query, state, style, transition, trigger} from '@angular/animations';
|
||||
import {animate, query, state, style, transition, trigger} from '@angular/animations';
|
||||
import {AnimationDriver, ɵAnimationEngine, ɵWebAnimationsDriver, ɵWebAnimationsPlayer, ɵsupportsWebAnimations} from '@angular/animations/browser';
|
||||
import {TransitionAnimationPlayer} from '@angular/animations/browser/src/render/transition_animation_engine';
|
||||
import {AnimationGroupPlayer} from '@angular/animations/src/players/animation_group_player';
|
||||
import {Component} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {browserDetection} from '@angular/platform-browser/testing/src/browser_util';
|
||||
|
||||
import {TestBed} from '../../testing';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
|
||||
(function() {
|
||||
// these tests are only mean't to be run within the DOM (for now)
|
||||
@ -242,7 +242,8 @@ import {TestBed} from '../../testing';
|
||||
]);
|
||||
});
|
||||
|
||||
it('should treat * styles as ! for queried items that are collected in a container that is being removed',
|
||||
fixmeIvy('unknown').it(
|
||||
'should treat * styles as ! for queried items that are collected in a container that is being removed',
|
||||
() => {
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
|
@ -13,6 +13,7 @@ import {ComponentFixture, TestBed, fakeAsync} from '@angular/core/testing';
|
||||
import {By} from '@angular/platform-browser/src/dom/debug/by';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
|
||||
export function createUrlResolverWithoutPackagePrefix(): UrlResolver {
|
||||
return new UrlResolver();
|
||||
@ -445,7 +446,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
}));
|
||||
|
||||
|
||||
it('should ignore empty bindings', fakeAsync(() => {
|
||||
fixmeIvy('FW-814: Bindings with an empty value should be ignored in the compiler')
|
||||
.it('should ignore empty bindings', fakeAsync(() => {
|
||||
const ctx = _bindSimpleProp('[someProp]', TestData);
|
||||
ctx.componentInstance.a = 'value';
|
||||
ctx.detectChanges(false);
|
||||
@ -537,7 +539,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
expect(renderLog.log).toEqual(['someProp=Megatron']);
|
||||
}));
|
||||
|
||||
it('should record unwrapped values via ngOnChanges', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should record unwrapped values via ngOnChanges', fakeAsync(() => {
|
||||
const ctx = createCompFixture(
|
||||
'<div [testDirective]="\'aName\' | wrappedPipe" [a]="1" [b]="2 | wrappedPipe"></div>');
|
||||
const dir: TestDirective = queryDirs(ctx.debugElement, TestDirective)[0];
|
||||
@ -588,7 +591,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
|
||||
}));
|
||||
|
||||
it('should call pure pipes that are used multiple times only when the arguments change',
|
||||
fixmeIvy('unknown').it(
|
||||
'should call pure pipes that are used multiple times only when the arguments change',
|
||||
fakeAsync(() => {
|
||||
const ctx = createCompFixture(
|
||||
`<div [someProp]="name | countingPipe"></div><div [someProp]="age | countingPipe"></div>` +
|
||||
@ -994,7 +998,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual([]);
|
||||
}));
|
||||
|
||||
it('should not call ngAfterViewInit again if it throws', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should not call ngAfterViewInit again if it throws', fakeAsync(() => {
|
||||
const ctx =
|
||||
createCompFixture('<div testDirective="dir" throwOn="ngAfterViewInit"></div>');
|
||||
|
||||
@ -1073,7 +1078,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
});
|
||||
|
||||
describe('ngOnDestroy', () => {
|
||||
it('should be called on view destruction', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should be called on view destruction', fakeAsync(() => {
|
||||
const ctx = createCompFixture('<div testDirective="dir"></div>');
|
||||
ctx.detectChanges(false);
|
||||
|
||||
@ -1082,7 +1088,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
expect(directiveLog.filter(['ngOnDestroy'])).toEqual(['dir.ngOnDestroy']);
|
||||
}));
|
||||
|
||||
it('should be called after processing the content and view children', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should be called after processing the content and view children', fakeAsync(() => {
|
||||
TestBed.overrideComponent(AnotherComponent, {
|
||||
set: new Component(
|
||||
{selector: 'other-cmp', template: '<div testDirective="viewChild"></div>'})
|
||||
@ -1102,7 +1109,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
]);
|
||||
}));
|
||||
|
||||
it('should be called in reverse order so the child is always notified before the parent',
|
||||
fixmeIvy('unknown').it(
|
||||
'should be called in reverse order so the child is always notified before the parent',
|
||||
fakeAsync(() => {
|
||||
const ctx = createCompFixture(
|
||||
'<div testDirective="parent"><div testDirective="child"></div></div><div testDirective="sibling"></div>');
|
||||
@ -1115,7 +1123,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
]);
|
||||
}));
|
||||
|
||||
it('should deliver synchronous events to parent', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should deliver synchronous events to parent', fakeAsync(() => {
|
||||
const ctx = createCompFixture('<div (destroy)="a=$event" onDestroyDirective></div>');
|
||||
|
||||
ctx.detectChanges(false);
|
||||
@ -1124,7 +1133,7 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
expect(ctx.componentInstance.a).toEqual('destroyed');
|
||||
}));
|
||||
|
||||
it('should call ngOnDestroy on pipes', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it('should call ngOnDestroy on pipes', fakeAsync(() => {
|
||||
const ctx = createCompFixture('{{true | pipeWithOnDestroy }}');
|
||||
|
||||
ctx.detectChanges(false);
|
||||
@ -1135,11 +1144,12 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
]);
|
||||
}));
|
||||
|
||||
it('should call ngOnDestroy on an injectable class', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it('should call ngOnDestroy on an injectable class', fakeAsync(() => {
|
||||
TestBed.overrideDirective(
|
||||
TestDirective, {set: {providers: [InjectableWithLifecycle]}});
|
||||
|
||||
const ctx = createCompFixture('<div testDirective="dir"></div>', TestComponent);
|
||||
const ctx = createCompFixture(
|
||||
'<div testDirective="dir"></div>', TestComponent);
|
||||
|
||||
ctx.debugElement.children[0].injector.get(InjectableWithLifecycle);
|
||||
ctx.detectChanges(false);
|
||||
@ -1155,7 +1165,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
});
|
||||
|
||||
describe('enforce no new changes', () => {
|
||||
it('should throw when a record gets changed after it has been checked', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should throw when a record gets changed after it has been checked', fakeAsync(() => {
|
||||
@Directive({selector: '[changed]'})
|
||||
class ChangingDirective {
|
||||
@Input() changed: any;
|
||||
@ -1168,10 +1179,12 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
ctx.componentInstance.b = 1;
|
||||
|
||||
expect(() => ctx.checkNoChanges())
|
||||
.toThrowError(/Previous value: 'changed: undefined'\. Current value: 'changed: 1'/g);
|
||||
.toThrowError(
|
||||
/Previous value: 'changed: undefined'\. Current value: 'changed: 1'/g);
|
||||
}));
|
||||
|
||||
it('should warn when the view has been created in a cd hook', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should warn when the view has been created in a cd hook', fakeAsync(() => {
|
||||
const ctx = createCompFixture('<div *gh9882>{{ a }}</div>', TestData);
|
||||
ctx.componentInstance.a = 1;
|
||||
expect(() => ctx.detectChanges())
|
||||
@ -1187,7 +1200,7 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
expect(() => ctx.checkNoChanges()).not.toThrow();
|
||||
}));
|
||||
|
||||
it('should not break the next run', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it('should not break the next run', fakeAsync(() => {
|
||||
const ctx = _bindSimpleValue('a', TestData);
|
||||
ctx.componentInstance.a = 'value';
|
||||
expect(() => ctx.checkNoChanges()).toThrow();
|
||||
@ -1198,7 +1211,7 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
});
|
||||
|
||||
describe('mode', () => {
|
||||
it('Detached', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it('Detached', fakeAsync(() => {
|
||||
const ctx = createCompFixture('<comp-with-ref></comp-with-ref>');
|
||||
const cmp: CompWithRef = queryDirs(ctx.debugElement, CompWithRef)[0];
|
||||
cmp.value = 'hello';
|
||||
@ -1260,13 +1273,14 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
|
||||
}));
|
||||
|
||||
it('Reattaches in the original cd mode', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it('Reattaches in the original cd mode', fakeAsync(() => {
|
||||
const ctx = createCompFixture('<push-cmp></push-cmp>');
|
||||
const cmp: PushComp = queryDirs(ctx.debugElement, PushComp)[0];
|
||||
cmp.changeDetectorRef.detach();
|
||||
cmp.changeDetectorRef.reattach();
|
||||
|
||||
// renderCount should NOT be incremented with each CD as CD mode should be resetted to
|
||||
// renderCount should NOT be incremented with each CD as CD mode
|
||||
// should be resetted to
|
||||
// on-push
|
||||
ctx.detectChanges();
|
||||
expect(cmp.renderCount).toBeGreaterThan(0);
|
||||
@ -1279,7 +1293,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
});
|
||||
|
||||
describe('multi directive order', () => {
|
||||
it('should follow the DI order for the same element', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should follow the DI order for the same element', fakeAsync(() => {
|
||||
const ctx =
|
||||
createCompFixture('<div orderCheck2="2" orderCheck0="0" orderCheck1="1"></div>');
|
||||
|
||||
@ -1424,7 +1439,8 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
expect(log).toEqual(['inner-start', 'main-tpl', 'outer-tpl']);
|
||||
});
|
||||
|
||||
it('should dirty check projected views if the declaration place is dirty checked', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should dirty check projected views if the declaration place is dirty checked', () => {
|
||||
ctx.detectChanges(false);
|
||||
log = [];
|
||||
innerComp.cdRef.detach();
|
||||
@ -1516,7 +1532,7 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||
childThrows: LifetimeMethods;
|
||||
}
|
||||
|
||||
describe('calling init', () => {
|
||||
fixmeIvy('unknown').describe('calling init', () => {
|
||||
function initialize(options: Options) {
|
||||
@Component({selector: 'my-child', template: ''})
|
||||
class MyChild {
|
||||
|
@ -700,7 +700,8 @@ function declareTests(config?: {useJit: boolean}) {
|
||||
});
|
||||
|
||||
if (getDOM().supportsDOMEvents()) {
|
||||
it('should be checked when an async pipe requests a check', fakeAsync(() => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should be checked when an async pipe requests a check', fakeAsync(() => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [MyComp, PushCmpWithAsyncPipe], imports: [CommonModule]});
|
||||
const template = '<push-cmp-with-async #cmp></push-cmp-with-async>';
|
||||
@ -1872,7 +1873,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||
|
||||
if (getDOM().supportsDOMEvents()) {
|
||||
describe('svg', () => {
|
||||
it('should support svg elements', () => {
|
||||
fixmeIvy('unknown').it('should support svg elements', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||
const template = '<svg><use xlink:href="Port" /></svg>';
|
||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||
@ -1891,7 +1892,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||
expect(firstAttribute.namespaceURI).toEqual('http://www.w3.org/1999/xlink');
|
||||
});
|
||||
|
||||
it('should support foreignObjects with document fragments', () => {
|
||||
fixmeIvy('unknown').it('should support foreignObjects with document fragments', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp]});
|
||||
const template =
|
||||
'<svg><foreignObject><xhtml:div><p>Test</p></xhtml:div></foreignObject></svg>';
|
||||
@ -1913,7 +1914,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||
|
||||
describe('attributes', () => {
|
||||
|
||||
it('should support attributes with namespace', () => {
|
||||
fixmeIvy('unknown').it('should support attributes with namespace', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeCmp]});
|
||||
const template = '<svg:use xlink:href="#id" />';
|
||||
TestBed.overrideComponent(SomeCmp, {set: {template}});
|
||||
@ -1924,7 +1925,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||
.toEqual('#id');
|
||||
});
|
||||
|
||||
it('should support binding to attributes with namespace', () => {
|
||||
fixmeIvy('unknown').it('should support binding to attributes with namespace', () => {
|
||||
TestBed.configureTestingModule({declarations: [MyComp, SomeCmp]});
|
||||
const template = '<svg:use [attr.xlink:href]="value" />';
|
||||
TestBed.overrideComponent(SomeCmp, {set: {template}});
|
||||
|
@ -370,7 +370,8 @@ describe('projection', () => {
|
||||
});
|
||||
|
||||
if (getDOM().supportsNativeShadowDOM()) {
|
||||
it('should support native content projection and isolate styles per component', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should support native content projection and isolate styles per component', () => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleNative1, SimpleNative2]});
|
||||
TestBed.overrideComponent(MainComp, {
|
||||
set: {
|
||||
|
@ -428,7 +428,7 @@ function declareTestsUsingBootstrap() {
|
||||
if (getDOM().supportsDOMEvents()) {
|
||||
// This test needs a real DOM....
|
||||
|
||||
it('should keep change detecting if there was an error', (done) => {
|
||||
fixmeIvy('unknown').it('should keep change detecting if there was an error', (done) => {
|
||||
@Component({
|
||||
selector: COMP_SELECTOR,
|
||||
template:
|
||||
|
@ -10,6 +10,7 @@ import {Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, Compon
|
||||
import {ComponentFixture, TestBed, fakeAsync} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
|
||||
@Directive({selector: '[simpleDirective]'})
|
||||
class SimpleDirective {
|
||||
@ -291,7 +292,7 @@ class TestComp {
|
||||
expect(el.children[0].injector.get('injectable2')).toEqual('injectable1-injectable2');
|
||||
});
|
||||
|
||||
it('should instantiate viewProviders that have dependencies', () => {
|
||||
fixmeIvy('unknown').it('should instantiate viewProviders that have dependencies', () => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleComponent]});
|
||||
const viewProviders = [
|
||||
{provide: 'injectable1', useValue: 'injectable1'}, {
|
||||
@ -428,7 +429,7 @@ class TestComp {
|
||||
expect(ctx.debugElement.injector.get('eager2')).toBe('v2: v1');
|
||||
});
|
||||
|
||||
it('should inject providers that were declared after it', () => {
|
||||
fixmeIvy('unknown').it('should inject providers that were declared after it', () => {
|
||||
@Component({
|
||||
template: '',
|
||||
providers: [
|
||||
@ -464,7 +465,7 @@ class TestComp {
|
||||
expect(comp.componentInstance.a).toBe('aValue');
|
||||
});
|
||||
|
||||
it('should support ngOnDestroy for lazy providers', () => {
|
||||
fixmeIvy('unknown').it('should support ngOnDestroy for lazy providers', () => {
|
||||
let created = false;
|
||||
let destroyed = false;
|
||||
|
||||
@ -496,7 +497,7 @@ class TestComp {
|
||||
expect(destroyed).toBe(true);
|
||||
});
|
||||
|
||||
it('should instantiate view providers lazily', () => {
|
||||
fixmeIvy('unknown').it('should instantiate view providers lazily', () => {
|
||||
let created = false;
|
||||
TestBed.configureTestingModule({declarations: [SimpleComponent]});
|
||||
TestBed.overrideComponent(
|
||||
@ -551,27 +552,34 @@ class TestComp {
|
||||
.toEqual('parentService');
|
||||
});
|
||||
|
||||
it('should instantiate directives that depend on providers of a component', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should instantiate directives that depend on providers of a component', () => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsService]});
|
||||
TestBed.overrideComponent(
|
||||
SimpleComponent, {set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
|
||||
TestBed.overrideComponent(SimpleComponent, {set: {template: '<div needsService></div>'}});
|
||||
SimpleComponent,
|
||||
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
|
||||
TestBed.overrideComponent(
|
||||
SimpleComponent, {set: {template: '<div needsService></div>'}});
|
||||
const el = createComponent('<div simpleComponent></div>');
|
||||
expect(el.children[0].children[0].injector.get(NeedsService).service)
|
||||
.toEqual('hostService');
|
||||
});
|
||||
|
||||
it('should instantiate directives that depend on view providers of a component', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should instantiate directives that depend on view providers of a component', () => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsService]});
|
||||
TestBed.overrideComponent(
|
||||
SimpleComponent, {set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
|
||||
TestBed.overrideComponent(SimpleComponent, {set: {template: '<div needsService></div>'}});
|
||||
SimpleComponent,
|
||||
{set: {providers: [{provide: 'service', useValue: 'hostService'}]}});
|
||||
TestBed.overrideComponent(
|
||||
SimpleComponent, {set: {template: '<div needsService></div>'}});
|
||||
const el = createComponent('<div simpleComponent></div>');
|
||||
expect(el.children[0].children[0].injector.get(NeedsService).service)
|
||||
.toEqual('hostService');
|
||||
});
|
||||
|
||||
it('should instantiate directives in a root embedded view that depend on view providers of a component',
|
||||
fixmeIvy('unknown').it(
|
||||
'should instantiate directives in a root embedded view that depend on view providers of a component',
|
||||
() => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsService]});
|
||||
TestBed.overrideComponent(
|
||||
@ -590,14 +598,15 @@ class TestComp {
|
||||
expect(el.children[0].injector.get(NeedsAppService).service).toEqual('appService');
|
||||
});
|
||||
|
||||
it('should not instantiate a directive with cyclic dependencies', () => {
|
||||
fixmeIvy('unknown').it('should not instantiate a directive with cyclic dependencies', () => {
|
||||
TestBed.configureTestingModule({declarations: [CycleDirective]});
|
||||
expect(() => createComponent('<div cycleDirective></div>'))
|
||||
.toThrowError(
|
||||
/Template parse errors:\nCannot instantiate cyclic dependency! CycleDirective \("\[ERROR ->\]<div cycleDirective><\/div>"\): .*TestComp.html@0:0/);
|
||||
});
|
||||
|
||||
it('should not instantiate a directive in a view that has a host dependency on providers' +
|
||||
fixmeIvy('unknown').it(
|
||||
'should not instantiate a directive in a view that has a host dependency on providers' +
|
||||
' of the component',
|
||||
() => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsServiceFromHost]});
|
||||
@ -612,7 +621,8 @@ class TestComp {
|
||||
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
|
||||
});
|
||||
|
||||
it('should not instantiate a directive in a view that has a host dependency on providers' +
|
||||
fixmeIvy('unknown').it(
|
||||
'should not instantiate a directive in a view that has a host dependency on providers' +
|
||||
' of a decorator directive',
|
||||
() => {
|
||||
TestBed.configureTestingModule(
|
||||
@ -628,13 +638,14 @@ class TestComp {
|
||||
/Template parse errors:\nNo provider for service \("\[ERROR ->\]<div needsServiceFromHost><div>"\): .*SimpleComponent.html@0:0/);
|
||||
});
|
||||
|
||||
it('should not instantiate a directive in a view that has a self dependency on a parent directive',
|
||||
fixmeIvy('unknown').it(
|
||||
'should not instantiate a directive in a view that has a self dependency on a parent directive',
|
||||
() => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [SimpleDirective, NeedsDirectiveFromSelf]});
|
||||
expect(
|
||||
() =>
|
||||
createComponent('<div simpleDirective><div needsDirectiveFromSelf></div></div>'))
|
||||
() => createComponent(
|
||||
'<div simpleDirective><div needsDirectiveFromSelf></div></div>'))
|
||||
.toThrowError(
|
||||
/Template parse errors:\nNo provider for SimpleDirective \("<div simpleDirective>\[ERROR ->\]<div needsDirectiveFromSelf><\/div><\/div>"\): .*TestComp.html@0:21/);
|
||||
});
|
||||
@ -662,8 +673,10 @@ class TestComp {
|
||||
expect(d.dependency).toBeNull();
|
||||
});
|
||||
|
||||
it('should instantiate directives that depends on the host component', () => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleComponent, NeedsComponentFromHost]});
|
||||
fixmeIvy('unknown').it(
|
||||
'should instantiate directives that depends on the host component', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [SimpleComponent, NeedsComponentFromHost]});
|
||||
TestBed.overrideComponent(
|
||||
SimpleComponent, {set: {template: '<div needsComponentFromHost></div>'}});
|
||||
const el = createComponent('<div simpleComponent></div>');
|
||||
@ -671,13 +684,16 @@ class TestComp {
|
||||
expect(d.dependency).toBeAnInstanceOf(SimpleComponent);
|
||||
});
|
||||
|
||||
it('should instantiate host views for components that have a @Host dependency ', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should instantiate host views for components that have a @Host dependency ', () => {
|
||||
TestBed.configureTestingModule({declarations: [NeedsHostAppService]});
|
||||
const el = createComponent('', [], NeedsHostAppService);
|
||||
expect(el.componentInstance.service).toEqual('appService');
|
||||
});
|
||||
|
||||
it('should not instantiate directives that depend on other directives on the host element', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should not instantiate directives that depend on other directives on the host element',
|
||||
() => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [SimpleComponent, SimpleDirective, NeedsDirectiveFromHost]});
|
||||
TestBed.overrideComponent(
|
||||
@ -687,7 +703,8 @@ class TestComp {
|
||||
/Template parse errors:\nNo provider for SimpleDirective \("\[ERROR ->\]<div needsDirectiveFromHost><\/div>"\): .*SimpleComponent.html@0:0/);
|
||||
});
|
||||
|
||||
it('should allow to use the NgModule injector from a root ViewContainerRef.parentInjector',
|
||||
fixmeIvy('unknown').it(
|
||||
'should allow to use the NgModule injector from a root ViewContainerRef.parentInjector',
|
||||
() => {
|
||||
@Component({template: ''})
|
||||
class MyComp {
|
||||
@ -734,7 +751,8 @@ class TestComp {
|
||||
.toBe(el.children[0].nativeElement);
|
||||
});
|
||||
|
||||
it('should inject ChangeDetectorRef of the component\'s view into the component', () => {
|
||||
fixmeIvy('unknown').it(
|
||||
'should inject ChangeDetectorRef of the component\'s view into the component', () => {
|
||||
TestBed.configureTestingModule({declarations: [PushComponentNeedsChangeDetectorRef]});
|
||||
const cf = createComponentFixture('<div componentNeedsChangeDetectorRef></div>');
|
||||
cf.detectChanges();
|
||||
@ -748,9 +766,12 @@ class TestComp {
|
||||
expect(compEl.nativeElement).toHaveText('1');
|
||||
});
|
||||
|
||||
it('should inject ChangeDetectorRef of the containing component into directives', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]});
|
||||
fixmeIvy('unknown').it(
|
||||
'should inject ChangeDetectorRef of the containing component into directives', () => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations:
|
||||
[PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]
|
||||
});
|
||||
TestBed.overrideComponent(PushComponentNeedsChangeDetectorRef, {
|
||||
set: {
|
||||
template:
|
||||
@ -765,18 +786,23 @@ class TestComp {
|
||||
comp.counter = 1;
|
||||
cf.detectChanges();
|
||||
expect(compEl.nativeElement).toHaveText('0');
|
||||
expect(compEl.children[0].injector.get(DirectiveNeedsChangeDetectorRef).changeDetectorRef)
|
||||
expect(
|
||||
compEl.children[0].injector.get(DirectiveNeedsChangeDetectorRef).changeDetectorRef)
|
||||
.toEqual(comp.changeDetectorRef);
|
||||
expect(compEl.children[1].injector.get(DirectiveNeedsChangeDetectorRef).changeDetectorRef)
|
||||
expect(
|
||||
compEl.children[1].injector.get(DirectiveNeedsChangeDetectorRef).changeDetectorRef)
|
||||
.toEqual(comp.changeDetectorRef);
|
||||
comp.changeDetectorRef.markForCheck();
|
||||
cf.detectChanges();
|
||||
expect(compEl.nativeElement).toHaveText('1');
|
||||
});
|
||||
|
||||
it('should inject ChangeDetectorRef of a same element component into a directive', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]});
|
||||
fixmeIvy('unknown').it(
|
||||
'should inject ChangeDetectorRef of a same element component into a directive', () => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations:
|
||||
[PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]
|
||||
});
|
||||
const cf = createComponentFixture(
|
||||
'<div componentNeedsChangeDetectorRef directiveNeedsChangeDetectorRef></div>');
|
||||
cf.detectChanges();
|
||||
@ -791,10 +817,13 @@ class TestComp {
|
||||
expect(compEl.nativeElement).toHaveText('1');
|
||||
});
|
||||
|
||||
it(`should not inject ChangeDetectorRef of a parent element's component into a directive`, () => {
|
||||
fixmeIvy('unknown').it(
|
||||
`should not inject ChangeDetectorRef of a parent element's component into a directive`,
|
||||
() => {
|
||||
TestBed
|
||||
.configureTestingModule({
|
||||
declarations: [PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]
|
||||
declarations:
|
||||
[PushComponentNeedsChangeDetectorRef, DirectiveNeedsChangeDetectorRef]
|
||||
})
|
||||
.overrideComponent(
|
||||
PushComponentNeedsChangeDetectorRef,
|
||||
@ -822,7 +851,7 @@ class TestComp {
|
||||
.toBe(el.children[0].nativeElement);
|
||||
});
|
||||
|
||||
it('should inject ViewContainerRef', () => {
|
||||
fixmeIvy('unknown').it('should inject ViewContainerRef', () => {
|
||||
@Component({template: ''})
|
||||
class TestComp {
|
||||
constructor(public vcr: ViewContainerRef) {}
|
||||
@ -847,7 +876,7 @@ class TestComp {
|
||||
expect(component.instance.vcr.parentInjector.get('someToken')).toBe('someNewValue');
|
||||
});
|
||||
|
||||
it('should inject TemplateRef', () => {
|
||||
fixmeIvy('unknown').it('should inject TemplateRef', () => {
|
||||
TestBed.configureTestingModule({declarations: [NeedsViewContainerRef, NeedsTemplateRef]});
|
||||
const el =
|
||||
createComponent('<ng-template needsViewContainerRef needsTemplateRef></ng-template>');
|
||||
@ -855,7 +884,7 @@ class TestComp {
|
||||
.toEqual(el.childNodes[0].injector.get(NeedsViewContainerRef).viewContainer.element);
|
||||
});
|
||||
|
||||
it('should throw if there is no TemplateRef', () => {
|
||||
fixmeIvy('unknown').it('should throw if there is no TemplateRef', () => {
|
||||
TestBed.configureTestingModule({declarations: [NeedsTemplateRef]});
|
||||
expect(() => createComponent('<div needsTemplateRef></div>'))
|
||||
.toThrowError(/No provider for TemplateRef!/);
|
||||
@ -870,7 +899,7 @@ class TestComp {
|
||||
});
|
||||
|
||||
describe('pipes', () => {
|
||||
it('should instantiate pipes that have dependencies', () => {
|
||||
fixmeIvy('unknown').it('should instantiate pipes that have dependencies', () => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleDirective, PipeNeedsService]});
|
||||
|
||||
const el = createComponent(
|
||||
@ -879,7 +908,7 @@ class TestComp {
|
||||
expect(el.children[0].injector.get(SimpleDirective).value.service).toEqual('pipeService');
|
||||
});
|
||||
|
||||
it('should overwrite pipes with later entry in the pipes array', () => {
|
||||
fixmeIvy('unknown').it('should overwrite pipes with later entry in the pipes array', () => {
|
||||
TestBed.configureTestingModule(
|
||||
{declarations: [SimpleDirective, DuplicatePipe1, DuplicatePipe2]});
|
||||
const el = createComponent('<div [simpleDirective]="true | duplicatePipe"></div>');
|
||||
@ -898,7 +927,7 @@ class TestComp {
|
||||
expect(el.children[0].injector.get(SimpleDirective).value.changeDetectorRef).toEqual(cdRef);
|
||||
});
|
||||
|
||||
it('should cache pure pipes', () => {
|
||||
fixmeIvy('unknown').it('should cache pure pipes', () => {
|
||||
TestBed.configureTestingModule({declarations: [SimpleDirective, PurePipe]});
|
||||
const el = createComponent(
|
||||
'<div [simpleDirective]="true | purePipe"></div><div [simpleDirective]="true | purePipe"></div>' +
|
||||
|
@ -9,6 +9,7 @@
|
||||
import {SecurityContext} from '@angular/core';
|
||||
import {ArgumentType, BindingFlags, NodeCheckFn, NodeFlags, Services, ViewData, ViewFlags, ViewState, asElementData, directiveDef, elementDef, rootRenderNodes} from '@angular/core/src/view/index';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
|
||||
import {callMostRecentEventListenerHandler, compViewDef, createAndGetRootNodes, createRootView, isBrowser, recordNodeToRemove} from './helper';
|
||||
|
||||
@ -199,7 +200,8 @@ const addEventListener = '__zone_symbol__addEventListener' as 'addEventListener'
|
||||
});
|
||||
|
||||
if (isBrowser()) {
|
||||
it('should support OnPush components', () => {
|
||||
fixmeIvy('FW-665: Discovery util fails with "Unable to find context associated with ..."')
|
||||
.it('should support OnPush components', () => {
|
||||
let compInputValue: any;
|
||||
class AComp {
|
||||
a: any;
|
||||
@ -207,7 +209,8 @@ const addEventListener = '__zone_symbol__addEventListener' as 'addEventListener'
|
||||
|
||||
const update = jasmine.createSpy('updater');
|
||||
|
||||
const addListenerSpy = spyOn(HTMLElement.prototype, addEventListener).and.callThrough();
|
||||
const addListenerSpy =
|
||||
spyOn(HTMLElement.prototype, addEventListener).and.callThrough();
|
||||
|
||||
const {view} = createAndGetRootNodes(compViewDef(
|
||||
[
|
||||
|
@ -11,6 +11,7 @@ import {getDebugContext} from '@angular/core/src/errors';
|
||||
import {BindingFlags, NodeFlags, Services, ViewData, ViewDefinition, asElementData, elementDef} from '@angular/core/src/view/index';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
|
||||
import {ARG_TYPE_VALUES, callMostRecentEventListenerHandler, checkNodeInlineOrDynamic, compViewDef, createAndGetRootNodes, isBrowser, recordNodeToRemove} from './helper';
|
||||
|
||||
@ -184,7 +185,8 @@ const removeEventListener = '__zone_symbol__removeEventListener' as 'removeEvent
|
||||
return result;
|
||||
}
|
||||
|
||||
it('should listen to DOM events', () => {
|
||||
fixmeIvy('FW-665: Discovery util fails with "Unable to find context associated with ..."')
|
||||
.it('should listen to DOM events', () => {
|
||||
const handleEventSpy = jasmine.createSpy('handleEvent');
|
||||
const removeListenerSpy =
|
||||
spyOn(HTMLElement.prototype, removeEventListener).and.callThrough();
|
||||
@ -251,7 +253,8 @@ const removeEventListener = '__zone_symbol__removeEventListener' as 'removeEvent
|
||||
expect(removeListenerSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should preventDefault only if the handler returns false', () => {
|
||||
fixmeIvy('FW-665: Discovery util fails with "Unable to find context associated with ..."')
|
||||
.it('should preventDefault only if the handler returns false', () => {
|
||||
let eventHandlerResult: any;
|
||||
let preventDefaultSpy: jasmine.Spy = undefined !;
|
||||
|
||||
@ -279,9 +282,11 @@ const removeEventListener = '__zone_symbol__removeEventListener' as 'removeEvent
|
||||
expect(preventDefaultSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should report debug info on event errors', () => {
|
||||
fixmeIvy('FW-665: Discovery util fails with "Unable to find context associated with ..."')
|
||||
.it('should report debug info on event errors', () => {
|
||||
const handleErrorSpy = spyOn(TestBed.get(ErrorHandler), 'handleError');
|
||||
const addListenerSpy = spyOn(HTMLElement.prototype, addEventListener).and.callThrough();
|
||||
const addListenerSpy =
|
||||
spyOn(HTMLElement.prototype, addEventListener).and.callThrough();
|
||||
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
|
||||
0, NodeFlags.None, null, null, 0, 'button', null, null, [[null !, 'click']],
|
||||
() => { throw new Error('Test'); })]));
|
||||
|
Loading…
x
Reference in New Issue
Block a user