test(ivy): don't runViewEngine tests for ivy (#27645)

All the tests in `packages/core/test/view/` are specific to the `ViewEngine` and shouldn't run for ivy. This PR introduces a new BUILD.bazel file to run those tests separately.

PR Close #27645
This commit is contained in:
Olivier Combe 2018-12-13 11:02:59 +01:00 committed by Miško Hevery
parent b00aeeff37
commit 4df82bdbc1
4 changed files with 186 additions and 146 deletions

View File

@ -0,0 +1,52 @@
package(default_visibility = ["//visibility:public"])
load("//tools:defaults.bzl", "jasmine_node_test", "ts_library", "ts_web_test_suite")
ts_library(
name = "view_lib",
testonly = True,
srcs = glob(
["**/*.ts"],
),
deps = [
"//packages/core",
"//packages/core/testing",
"//packages/platform-browser",
"//packages/private/testing",
],
)
ts_library(
name = "view_node_only_lib",
testonly = True,
srcs = glob(["**/*_node_only_spec.ts"]),
deps = [
":view_lib",
"//packages/core",
"//packages/core/testing",
"//packages/private/testing",
],
)
jasmine_node_test(
name = "view",
bootstrap = ["angular/tools/testing/init_node_spec.js"],
tags = [
"no-ivy-aot",
],
deps = [
":view_lib",
":view_node_only_lib",
"//tools/testing:node",
],
)
ts_web_test_suite(
name = "view_web",
tags = [
"no-ivy-aot",
],
deps = [
":view_lib",
],
)

View File

@ -9,7 +9,6 @@
import {SecurityContext} from '@angular/core'; 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 {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 {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {fixmeIvy} from '@angular/private/testing';
import {callMostRecentEventListenerHandler, compViewDef, createAndGetRootNodes, createRootView, isBrowser, recordNodeToRemove} from './helper'; import {callMostRecentEventListenerHandler, compViewDef, createAndGetRootNodes, createRootView, isBrowser, recordNodeToRemove} from './helper';
@ -200,64 +199,62 @@ const addEventListener = '__zone_symbol__addEventListener' as 'addEventListener'
}); });
if (isBrowser()) { if (isBrowser()) {
fixmeIvy('FW-665: Discovery util fails with "Unable to find context associated with ..."') it('should support OnPush components', () => {
.it('should support OnPush components', () => { let compInputValue: any;
let compInputValue: any; class AComp {
class AComp { a: any;
a: any; }
}
const update = jasmine.createSpy('updater'); const update = jasmine.createSpy('updater');
const addListenerSpy = const addListenerSpy = spyOn(HTMLElement.prototype, addEventListener).and.callThrough();
spyOn(HTMLElement.prototype, addEventListener).and.callThrough();
const {view} = createAndGetRootNodes(compViewDef( const {view} = 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,
() => { () => {
return compViewDef( return compViewDef(
[ [
elementDef( elementDef(
0, NodeFlags.None, null, null, 0, 'span', null, null, 0, NodeFlags.None, null, null, 0, 'span', null, null,
[[null !, 'click']]), [[null !, 'click']]),
], ],
update, null, ViewFlags.OnPush); update, null, ViewFlags.OnPush);
}), }),
directiveDef(1, NodeFlags.Component, null, 0, AComp, [], {a: [0, 'a']}), directiveDef(1, NodeFlags.Component, null, 0, AComp, [], {a: [0, 'a']}),
], ],
(check, view) => { check(view, 1, ArgumentType.Inline, compInputValue); })); (check, view) => { check(view, 1, ArgumentType.Inline, compInputValue); }));
Services.checkAndUpdateView(view); Services.checkAndUpdateView(view);
// auto detach // auto detach
update.calls.reset(); update.calls.reset();
Services.checkAndUpdateView(view); Services.checkAndUpdateView(view);
expect(update).not.toHaveBeenCalled(); expect(update).not.toHaveBeenCalled();
// auto attach on input changes // auto attach on input changes
update.calls.reset(); update.calls.reset();
compInputValue = 'v1'; compInputValue = 'v1';
Services.checkAndUpdateView(view); Services.checkAndUpdateView(view);
expect(update).toHaveBeenCalled(); expect(update).toHaveBeenCalled();
// auto detach // auto detach
update.calls.reset(); update.calls.reset();
Services.checkAndUpdateView(view); Services.checkAndUpdateView(view);
expect(update).not.toHaveBeenCalled(); expect(update).not.toHaveBeenCalled();
// auto attach on events // auto attach on events
callMostRecentEventListenerHandler(addListenerSpy, 'SomeEvent'); callMostRecentEventListenerHandler(addListenerSpy, 'SomeEvent');
update.calls.reset(); update.calls.reset();
Services.checkAndUpdateView(view); Services.checkAndUpdateView(view);
expect(update).toHaveBeenCalled(); expect(update).toHaveBeenCalled();
// auto detach // auto detach
update.calls.reset(); update.calls.reset();
Services.checkAndUpdateView(view); Services.checkAndUpdateView(view);
expect(update).not.toHaveBeenCalled(); expect(update).not.toHaveBeenCalled();
}); });
} }
it('should not stop dirty checking views that threw errors in change detection', () => { it('should not stop dirty checking views that threw errors in change detection', () => {

View File

@ -11,7 +11,6 @@ import {getDebugContext} from '@angular/core/src/errors';
import {BindingFlags, NodeFlags, Services, ViewData, ViewDefinition, asElementData, elementDef} from '@angular/core/src/view/index'; import {BindingFlags, NodeFlags, Services, ViewData, ViewDefinition, asElementData, elementDef} from '@angular/core/src/view/index';
import {TestBed} from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; 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'; import {ARG_TYPE_VALUES, callMostRecentEventListenerHandler, checkNodeInlineOrDynamic, compViewDef, createAndGetRootNodes, isBrowser, recordNodeToRemove} from './helper';
@ -185,27 +184,26 @@ const removeEventListener = '__zone_symbol__removeEventListener' as 'removeEvent
return result; return result;
} }
fixmeIvy('FW-665: Discovery util fails with "Unable to find context associated with ..."') it('should listen to DOM events', () => {
.it('should listen to DOM events', () => { const handleEventSpy = jasmine.createSpy('handleEvent');
const handleEventSpy = jasmine.createSpy('handleEvent'); const removeListenerSpy =
const removeListenerSpy = spyOn(HTMLElement.prototype, removeEventListener).and.callThrough();
spyOn(HTMLElement.prototype, removeEventListener).and.callThrough(); const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef( 0, NodeFlags.None, null, null, 0, 'button', null, null, [[null !, 'click']],
0, NodeFlags.None, null, null, 0, 'button', null, null, [[null !, 'click']], handleEventSpy)]));
handleEventSpy)]));
rootNodes[0].click(); rootNodes[0].click();
expect(handleEventSpy).toHaveBeenCalled(); expect(handleEventSpy).toHaveBeenCalled();
let handleEventArgs = handleEventSpy.calls.mostRecent().args; let handleEventArgs = handleEventSpy.calls.mostRecent().args;
expect(handleEventArgs[0]).toBe(view); expect(handleEventArgs[0]).toBe(view);
expect(handleEventArgs[1]).toBe('click'); expect(handleEventArgs[1]).toBe('click');
expect(handleEventArgs[2]).toBeTruthy(); expect(handleEventArgs[2]).toBeTruthy();
Services.destroyView(view); Services.destroyView(view);
expect(removeListenerSpy).toHaveBeenCalled(); expect(removeListenerSpy).toHaveBeenCalled();
}); });
it('should listen to window events', () => { it('should listen to window events', () => {
const handleEventSpy = jasmine.createSpy('handleEvent'); const handleEventSpy = jasmine.createSpy('handleEvent');
@ -253,52 +251,49 @@ const removeEventListener = '__zone_symbol__removeEventListener' as 'removeEvent
expect(removeListenerSpy).toHaveBeenCalled(); expect(removeListenerSpy).toHaveBeenCalled();
}); });
fixmeIvy('FW-665: Discovery util fails with "Unable to find context associated with ..."') it('should preventDefault only if the handler returns false', () => {
.it('should preventDefault only if the handler returns false', () => { let eventHandlerResult: any;
let eventHandlerResult: any; let preventDefaultSpy: jasmine.Spy = undefined !;
let preventDefaultSpy: jasmine.Spy = undefined !;
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef( const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
0, NodeFlags.None, null, null, 0, 'button', null, null, [[null !, 'click']], 0, NodeFlags.None, null, null, 0, 'button', null, null, [[null !, 'click']],
(view, eventName, event) => { (view, eventName, event) => {
preventDefaultSpy = spyOn(event, 'preventDefault').and.callThrough(); preventDefaultSpy = spyOn(event, 'preventDefault').and.callThrough();
return eventHandlerResult; return eventHandlerResult;
})])); })]));
eventHandlerResult = undefined; eventHandlerResult = undefined;
rootNodes[0].click(); rootNodes[0].click();
expect(preventDefaultSpy).not.toHaveBeenCalled(); expect(preventDefaultSpy).not.toHaveBeenCalled();
eventHandlerResult = true; eventHandlerResult = true;
rootNodes[0].click(); rootNodes[0].click();
expect(preventDefaultSpy).not.toHaveBeenCalled(); expect(preventDefaultSpy).not.toHaveBeenCalled();
eventHandlerResult = 'someString'; eventHandlerResult = 'someString';
rootNodes[0].click(); rootNodes[0].click();
expect(preventDefaultSpy).not.toHaveBeenCalled(); expect(preventDefaultSpy).not.toHaveBeenCalled();
eventHandlerResult = false; eventHandlerResult = false;
rootNodes[0].click(); rootNodes[0].click();
expect(preventDefaultSpy).toHaveBeenCalled(); expect(preventDefaultSpy).toHaveBeenCalled();
}); });
fixmeIvy('FW-665: Discovery util fails with "Unable to find context associated with ..."') it('should report debug info on event errors', () => {
.it('should report debug info on event errors', () => { const handleErrorSpy = spyOn(TestBed.get(ErrorHandler), 'handleError');
const handleErrorSpy = spyOn(TestBed.get(ErrorHandler), 'handleError'); const addListenerSpy = spyOn(HTMLElement.prototype, addEventListener).and.callThrough();
const addListenerSpy = const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef(
spyOn(HTMLElement.prototype, addEventListener).and.callThrough(); 0, NodeFlags.None, null, null, 0, 'button', null, null, [[null !, 'click']],
const {view, rootNodes} = createAndAttachAndGetRootNodes(compViewDef([elementDef( () => { throw new Error('Test'); })]));
0, NodeFlags.None, null, null, 0, 'button', null, null, [[null !, 'click']],
() => { throw new Error('Test'); })]));
callMostRecentEventListenerHandler(addListenerSpy, 'SomeEvent'); callMostRecentEventListenerHandler(addListenerSpy, 'SomeEvent');
const err = handleErrorSpy.calls.mostRecent().args[0]; const err = handleErrorSpy.calls.mostRecent().args[0];
expect(err).toBeTruthy(); expect(err).toBeTruthy();
expect(err.message).toBe('Test'); expect(err.message).toBe('Test');
const debugCtx = getDebugContext(err); const debugCtx = getDebugContext(err);
expect(debugCtx.view).toBe(view); expect(debugCtx.view).toBe(view);
expect(debugCtx.nodeIndex).toBe(0); expect(debugCtx.nodeIndex).toBe(0);
}); });
}); });
} }
}); });

View File

@ -13,7 +13,6 @@ import {TestBed, withModule} from '@angular/core/testing';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {ARG_TYPE_VALUES, checkNodeInlineOrDynamic, createRootView, createAndGetRootNodes, compViewDef, compViewDefFactory} from './helper'; import {ARG_TYPE_VALUES, checkNodeInlineOrDynamic, createRootView, createAndGetRootNodes, compViewDef, compViewDefFactory} from './helper';
import {fixmeIvy} from '@angular/private/testing';
{ {
describe(`View Providers`, () => { describe(`View Providers`, () => {
@ -138,36 +137,34 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep instanceof Dep).toBeTruthy(); expect(instance.dep instanceof Dep).toBeTruthy();
}); });
fixmeIvy( it('should not inject deps from sibling root elements', () => {
'FW-807: NgModule injector doesn\'t report full search path if a token is not found') const rootElNodes = [
.it('should not inject deps from sibling root elements', () => { elementDef(0, NodeFlags.None, null, null, 1, 'span'),
const rootElNodes = [ directiveDef(1, NodeFlags.None, null, 0, Dep, []),
elementDef(0, NodeFlags.None, null, null, 1, 'span'), elementDef(2, NodeFlags.None, null, null, 1, 'span'),
directiveDef(1, NodeFlags.None, null, 0, Dep, []), directiveDef(3, NodeFlags.None, null, 0, SomeService, [Dep]),
elementDef(2, NodeFlags.None, null, null, 1, 'span'), ];
directiveDef(3, NodeFlags.None, null, 0, SomeService, [Dep]),
];
expect(() => createAndGetRootNodes(compViewDef(rootElNodes))) expect(() => createAndGetRootNodes(compViewDef(rootElNodes)))
.toThrowError( .toThrowError(
'StaticInjectorError(DynamicTestModule)[SomeService -> Dep]: \n' + 'StaticInjectorError(DynamicTestModule)[SomeService -> Dep]: \n' +
' StaticInjectorError(Platform: core)[SomeService -> Dep]: \n' + ' StaticInjectorError(Platform: core)[SomeService -> Dep]: \n' +
' NullInjectorError: No provider for Dep!'); ' NullInjectorError: No provider for Dep!');
const nonRootElNodes = [ const nonRootElNodes = [
elementDef(0, NodeFlags.None, null, null, 4, 'span'), elementDef(0, NodeFlags.None, null, null, 4, 'span'),
elementDef(1, NodeFlags.None, null, null, 1, 'span'), elementDef(1, NodeFlags.None, null, null, 1, 'span'),
directiveDef(2, NodeFlags.None, null, 0, Dep, []), directiveDef(2, NodeFlags.None, null, 0, Dep, []),
elementDef(3, NodeFlags.None, null, null, 1, 'span'), elementDef(3, NodeFlags.None, null, null, 1, 'span'),
directiveDef(4, NodeFlags.None, null, 0, SomeService, [Dep]), directiveDef(4, NodeFlags.None, null, 0, SomeService, [Dep]),
]; ];
expect(() => createAndGetRootNodes(compViewDef(nonRootElNodes))) expect(() => createAndGetRootNodes(compViewDef(nonRootElNodes)))
.toThrowError( .toThrowError(
'StaticInjectorError(DynamicTestModule)[SomeService -> Dep]: \n' + 'StaticInjectorError(DynamicTestModule)[SomeService -> Dep]: \n' +
' StaticInjectorError(Platform: core)[SomeService -> Dep]: \n' + ' StaticInjectorError(Platform: core)[SomeService -> Dep]: \n' +
' NullInjectorError: No provider for Dep!'); ' NullInjectorError: No provider for Dep!');
}); });
it('should inject from a parent element in a parent view', () => { it('should inject from a parent element in a parent view', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([
@ -183,17 +180,16 @@ import {fixmeIvy} from '@angular/private/testing';
expect(instance.dep instanceof Dep).toBeTruthy(); expect(instance.dep instanceof Dep).toBeTruthy();
}); });
fixmeIvy('FW-807: NgModule injector don\'t report full search path if a token is not found') it('should throw for missing dependencies', () => {
.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']) ])))
]))) .toThrowError(
.toThrowError( 'StaticInjectorError(DynamicTestModule)[nonExistingDep]: \n' +
'StaticInjectorError(DynamicTestModule)[nonExistingDep]: \n' + ' StaticInjectorError(Platform: core)[nonExistingDep]: \n' +
' StaticInjectorError(Platform: core)[nonExistingDep]: \n' + ' NullInjectorError: No provider for nonExistingDep!');
' NullInjectorError: No provider for nonExistingDep!'); });
});
it('should use null for optional missing dependencies', () => { it('should use null for optional missing dependencies', () => {
createAndGetRootNodes(compViewDef([ createAndGetRootNodes(compViewDef([