test(ivy): Have more descriptive names for LView
(#33449)
When debugging `LView`s it is easy to get lost since all of them have the same name. This change does three things: 1. It makes `TView` have an explicit type: - `Host`: for the top level `TView` for bootstrap - `Component`: for the `TView` which represents components template - `Embedded`: for the `TView` which represents an embedded template 2. It changes the name of `LView` to `LHostView`, `LComponentView`, and `LEmbeddedView` depending on the `TView` type. 3. For `LComponentView` and `LEmbeddedView` we also append the name of of the `context` constructor. The result is that we have `LView`s which are name as: `LComponentView_MyComponent` and `LEmbeddedView_NgIfContext`. The above changes will make it easier to understand the structure of the application when debugging. NOTE: All of these are behind `ngDevMode` and will get removed in production application. PR Close #33449
This commit is contained in:

committed by
Andrew Scott

parent
7bccef516f
commit
4924d73b8e
@ -7,11 +7,13 @@
|
||||
*/
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {Component, Directive, HostBinding, InjectionToken, ViewChild} from '@angular/core';
|
||||
import {isLView} from '@angular/core/src/render3/interfaces/type_checks';
|
||||
import {CONTEXT} from '@angular/core/src/render3/interfaces/view';
|
||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import {onlyInIvy} from '@angular/private/testing';
|
||||
|
||||
import {getHostElement, markDirty} from '../../src/render3/index';
|
||||
import {getComponent, getContext, getDebugNode, getDirectives, getInjectionTokens, getInjector, getListeners, getLocalRefs, getRootComponents, getViewComponent, loadLContext} from '../../src/render3/util/discovery_utils';
|
||||
import {getComponent, getComponentLView, getContext, getDebugNode, getDirectives, getInjectionTokens, getInjector, getListeners, getLocalRefs, getRootComponents, getViewComponent, loadLContext} from '../../src/render3/util/discovery_utils';
|
||||
|
||||
onlyInIvy('Ivy-specific utilities').describe('discovery utils', () => {
|
||||
let fixture: ComponentFixture<MyApp>;
|
||||
@ -87,6 +89,20 @@ onlyInIvy('Ivy-specific utilities').describe('discovery utils', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getComponentLView', () => {
|
||||
it('should retrieve component LView from element', () => {
|
||||
const childLView = getComponentLView(child[0]);
|
||||
expect(isLView(childLView)).toBe(true);
|
||||
expect(childLView[CONTEXT] instanceof Child).toBe(true);
|
||||
});
|
||||
|
||||
it('should retrieve component LView from component instance', () => {
|
||||
const childLView = getComponentLView(childComponent[0]);
|
||||
expect(isLView(childLView)).toBe(true);
|
||||
expect(childLView[CONTEXT] instanceof Child).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getContext', () => {
|
||||
it('should throw when called on non-element', () => {
|
||||
expect(() => getContext(dirA[0] as any)).toThrowError(/Expecting instance of DOM Node/);
|
||||
|
49
packages/core/test/acceptance/ngdevmode_debug_spec.ts
Normal file
49
packages/core/test/acceptance/ngdevmode_debug_spec.ts
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {Component} from '@angular/core';
|
||||
import {LView} from '@angular/core/src/render3/interfaces/view';
|
||||
import {getComponentLView, loadLContext} from '@angular/core/src/render3/util/discovery_utils';
|
||||
import {createNamedArrayType} from '@angular/core/src/util/named_array_type';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {onlyInIvy} from '@angular/private/testing';
|
||||
|
||||
const supportsArraySubclassing =
|
||||
createNamedArrayType('SupportsArraySubclassing').name === 'SupportsArraySubclassing';
|
||||
|
||||
onlyInIvy('Debug information exist in ivy only').describe('ngDevMode debug', () => {
|
||||
describe('LViewDebug', () => {
|
||||
supportsArraySubclassing && it('should name LView based on type', () => {
|
||||
@Component({
|
||||
template: `
|
||||
<ul>
|
||||
<li *ngIf="true">item</li>
|
||||
</ul>
|
||||
`
|
||||
})
|
||||
class MyApp {
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [MyApp], imports: [CommonModule]});
|
||||
const fixture = TestBed.createComponent(MyApp);
|
||||
const rootLView = loadLContext(fixture.nativeElement).lView;
|
||||
expect(rootLView.constructor.name).toEqual('LRootView');
|
||||
|
||||
const componentLView = getComponentLView(fixture.componentInstance);
|
||||
expect(componentLView.constructor.name).toEqual('LComponentView_MyApp');
|
||||
|
||||
const element: HTMLElement = fixture.nativeElement;
|
||||
fixture.detectChanges();
|
||||
const li = element.querySelector('li') !;
|
||||
const embeddedLView = loadLContext(li).lView;
|
||||
expect(embeddedLView.constructor.name).toEqual('LEmbeddedView_MyApp_li_1');
|
||||
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user