refactor(core): remove innerHTML and outerHTML testing utilities from DomAdapters (#32278)

PR Close #32278
This commit is contained in:
Kara Erickson 2019-08-22 14:14:36 -07:00 committed by atscott
parent 25f31f2a14
commit c3f9893d81
12 changed files with 32 additions and 49 deletions

View File

@ -8,8 +8,6 @@
import {PartialModule} from '@angular/compiler'; import {PartialModule} from '@angular/compiler';
import * as o from '@angular/compiler/src/output/output_ast'; import * as o from '@angular/compiler/src/output/output_ast';
import {MockAotCompilerHost} from '@angular/compiler/test/aot/test_util';
import {initDomAdapter} from '@angular/platform-browser/src/browser';
import * as ts from 'typescript'; import * as ts from 'typescript';
import {getAngularClassTransformerFactory} from '../../src/transformers/r3_transform'; import {getAngularClassTransformerFactory} from '../../src/transformers/r3_transform';

View File

@ -13,7 +13,6 @@ import {Component, ViewChild} from '@angular/core';
import {TestBed} from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {browserDetection} from '@angular/platform-browser/testing/src/browser_util'; import {browserDetection} from '@angular/platform-browser/testing/src/browser_util';
import {ivyEnabled} from '@angular/private/testing';
(function() { (function() {
// these tests are only mean't to be run within the DOM (for now) // these tests are only mean't to be run within the DOM (for now)

View File

@ -54,7 +54,7 @@ import {el, stringifyElement} from '@angular/platform-browser/testing/src/browse
expect(getDOM().isTextNode(t)).toBe(true); expect(getDOM().isTextNode(t)).toBe(true);
const d = getDOM().createElement('div'); const d = getDOM().createElement('div');
getDOM().appendChild(d, t); getDOM().appendChild(d, t);
expect(getDOM().getInnerHTML(d)).toEqual('hello'); expect(d.innerHTML).toEqual('hello');
}); });
it('should set className via the class attribute', () => { it('should set className via the class attribute', () => {

View File

@ -199,12 +199,12 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxProp = 'Some <span>HTML</span>'; fixture.componentInstance.ctxProp = 'Some <span>HTML</span>';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(fixture.debugElement.children[0].nativeElement)) expect(fixture.debugElement.children[0].nativeElement.innerHTML)
.toEqual('Some <span>HTML</span>'); .toEqual('Some <span>HTML</span>');
fixture.componentInstance.ctxProp = 'Some other <div>HTML</div>'; fixture.componentInstance.ctxProp = 'Some other <div>HTML</div>';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(fixture.debugElement.children[0].nativeElement)) expect(fixture.debugElement.children[0].nativeElement.innerHTML)
.toEqual('Some other <div>HTML</div>'); .toEqual('Some other <div>HTML</div>');
}); });
@ -1726,7 +1726,7 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxProp = 'hello'; fixture.componentInstance.ctxProp = 'hello';
fixture.detectChanges(); fixture.detectChanges();
const html = getDOM().getInnerHTML(fixture.nativeElement); const html = fixture.nativeElement.innerHTML;
expect(html).toContain('ng-reflect-dir-prop="hello"'); expect(html).toContain('ng-reflect-dir-prop="hello"');
}); });
@ -1737,7 +1737,7 @@ function declareTests(config?: {useJit: boolean}) {
const fixture = TestBed.createComponent(MyComp); const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges(); fixture.detectChanges();
const html = getDOM().getInnerHTML(fixture.nativeElement); const html = fixture.nativeElement.innerHTML;
expect(html).toContain('ng-reflect-dir-prop="hello"'); expect(html).toContain('ng-reflect-dir-prop="hello"');
expect(html).not.toContain('ng-reflect-title'); expect(html).not.toContain('ng-reflect-title');
}); });
@ -1747,7 +1747,7 @@ function declareTests(config?: {useJit: boolean}) {
const fixture = TestBed.createComponent(ParentCmp); const fixture = TestBed.createComponent(ParentCmp);
fixture.detectChanges(); fixture.detectChanges();
const html = getDOM().getInnerHTML(fixture.nativeElement); const html = fixture.nativeElement.innerHTML;
expect(html).toContain('ng-reflect-test_="hello"'); expect(html).toContain('ng-reflect-test_="hello"');
}); });
@ -1761,7 +1761,7 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxBoolProp = true; fixture.componentInstance.ctxBoolProp = true;
fixture.detectChanges(); fixture.detectChanges();
const html = getDOM().getInnerHTML(fixture.nativeElement); const html = fixture.nativeElement.innerHTML;
expect(html).toContain('"ng-reflect-ng-if": "true"'); expect(html).toContain('"ng-reflect-ng-if": "true"');
}); });
@ -1776,7 +1776,7 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxBoolProp = true; fixture.componentInstance.ctxBoolProp = true;
fixture.detectChanges(); fixture.detectChanges();
const html = getDOM().getInnerHTML(fixture.nativeElement); const html = fixture.nativeElement.innerHTML;
expect(html).toContain('"ng-reflect-ng-if": "true"'); expect(html).toContain('"ng-reflect-ng-if": "true"');
}); });
@ -1790,7 +1790,7 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxProp = 'hello'; fixture.componentInstance.ctxProp = 'hello';
fixture.detectChanges(); fixture.detectChanges();
const html = getDOM().getInnerHTML(fixture.nativeElement); const html = fixture.nativeElement.innerHTML;
expect(html).toContain('ng-reflect-dir-prop="hello"'); expect(html).toContain('ng-reflect-dir-prop="hello"');
expect(html).toContain('ng-reflect-dir-prop2="hello"'); expect(html).toContain('ng-reflect-dir-prop2="hello"');
}); });
@ -1802,7 +1802,7 @@ function declareTests(config?: {useJit: boolean}) {
const fixture = TestBed.createComponent(MyComp); const fixture = TestBed.createComponent(MyComp);
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('[ERROR]'); expect(fixture.nativeElement.innerHTML).toContain('[ERROR]');
}); });
it('should not reflect undefined values', () => { it('should not reflect undefined values', () => {
@ -1814,13 +1814,12 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxProp = 'hello'; fixture.componentInstance.ctxProp = 'hello';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(fixture.nativeElement)) expect(fixture.nativeElement.innerHTML).toContain('ng-reflect-dir-prop="hello"');
.toContain('ng-reflect-dir-prop="hello"');
fixture.componentInstance.ctxProp = undefined !; fixture.componentInstance.ctxProp = undefined !;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(fixture.nativeElement)).not.toContain('ng-reflect-'); expect(fixture.nativeElement.innerHTML).not.toContain('ng-reflect-');
}); });
it('should not reflect null values', () => { it('should not reflect null values', () => {
@ -1832,13 +1831,12 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxProp = 'hello'; fixture.componentInstance.ctxProp = 'hello';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(fixture.nativeElement)) expect(fixture.nativeElement.innerHTML).toContain('ng-reflect-dir-prop="hello"');
.toContain('ng-reflect-dir-prop="hello"');
fixture.componentInstance.ctxProp = null !; fixture.componentInstance.ctxProp = null !;
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(fixture.nativeElement)).not.toContain('ng-reflect-'); expect(fixture.nativeElement.innerHTML).not.toContain('ng-reflect-');
}); });
it('should reflect empty strings', () => { it('should reflect empty strings', () => {
@ -1850,7 +1848,7 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxProp = ''; fixture.componentInstance.ctxProp = '';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(fixture.nativeElement)).toContain('ng-reflect-dir-prop=""'); expect(fixture.nativeElement.innerHTML).toContain('ng-reflect-dir-prop=""');
}); });
it('should not reflect in comment nodes when the value changes to undefined', () => { it('should not reflect in comment nodes when the value changes to undefined', () => {
@ -1863,14 +1861,14 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxBoolProp = true; fixture.componentInstance.ctxBoolProp = true;
fixture.detectChanges(); fixture.detectChanges();
let html = getDOM().getInnerHTML(fixture.nativeElement); let html = fixture.nativeElement.innerHTML;
expect(html).toContain('bindings={'); expect(html).toContain('bindings={');
expect(html).toContain('"ng-reflect-ng-if": "true"'); expect(html).toContain('"ng-reflect-ng-if": "true"');
fixture.componentInstance.ctxBoolProp = undefined !; fixture.componentInstance.ctxBoolProp = undefined !;
fixture.detectChanges(); fixture.detectChanges();
html = getDOM().getInnerHTML(fixture.nativeElement); html = fixture.nativeElement.innerHTML;
expect(html).toContain('bindings={'); expect(html).toContain('bindings={');
expect(html).not.toContain('ng-reflect'); expect(html).not.toContain('ng-reflect');
}); });
@ -1885,14 +1883,14 @@ function declareTests(config?: {useJit: boolean}) {
fixture.componentInstance.ctxBoolProp = true; fixture.componentInstance.ctxBoolProp = true;
fixture.detectChanges(); fixture.detectChanges();
let html = getDOM().getInnerHTML(fixture.nativeElement); let html = fixture.nativeElement.innerHTML;
expect(html).toContain('bindings={'); expect(html).toContain('bindings={');
expect(html).toContain('"ng-reflect-ng-if": "true"'); expect(html).toContain('"ng-reflect-ng-if": "true"');
fixture.componentInstance.ctxBoolProp = null !; fixture.componentInstance.ctxBoolProp = null !;
fixture.detectChanges(); fixture.detectChanges();
html = getDOM().getInnerHTML(fixture.nativeElement); html = fixture.nativeElement.innerHTML;
expect(html).toContain('bindings={'); expect(html).toContain('bindings={');
expect(html).toContain('"ng-reflect-ng-if": null'); expect(html).toContain('"ng-reflect-ng-if": null');
}); });
@ -1928,8 +1926,7 @@ function declareTests(config?: {useJit: boolean}) {
dir.myAttr = 'aaa'; dir.myAttr = 'aaa';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getOuterHTML(fixture.debugElement.children[0].nativeElement)) expect(fixture.debugElement.children[0].nativeElement.outerHTML).toContain('my-attr="aaa"');
.toContain('my-attr="aaa"');
}); });
if (getDOM().supportsDOMEvents()) { if (getDOM().supportsDOMEvents()) {

View File

@ -574,7 +574,7 @@ describe('projection', () => {
const main = TestBed.createComponent(MainComp); const main = TestBed.createComponent(MainComp);
main.detectChanges(); main.detectChanges();
expect(getDOM().getInnerHTML(main.nativeElement)) expect(main.nativeElement.innerHTML)
.toEqual( .toEqual(
'<cmp-a><cmp-b><cmp-d><i>cmp-d</i></cmp-d></cmp-b>' + '<cmp-a><cmp-b><cmp-d><i>cmp-d</i></cmp-d></cmp-b>' +
'<cmp-c><b>cmp-c</b></cmp-c></cmp-a>'); '<cmp-c><b>cmp-c</b></cmp-c></cmp-a>');
@ -586,7 +586,7 @@ describe('projection', () => {
const main = TestBed.createComponent(MainComp); const main = TestBed.createComponent(MainComp);
main.detectChanges(); main.detectChanges();
expect(getDOM().getInnerHTML(main.nativeElement)) expect(main.nativeElement.innerHTML)
.toEqual( .toEqual(
'<cmp-a1>a1<cmp-b11>b11</cmp-b11><cmp-b12>b12</cmp-b12></cmp-a1>' + '<cmp-a1>a1<cmp-b11>b11</cmp-b11><cmp-b12>b12</cmp-b12></cmp-a1>' +
'<cmp-a2>a2<cmp-b21>b21</cmp-b21><cmp-b22>b22</cmp-b22></cmp-a2>'); '<cmp-a2>a2<cmp-b21>b21</cmp-b21><cmp-b22>b22</cmp-b22></cmp-a2>');

View File

@ -283,19 +283,19 @@ function declareTests(config?: {useJit: boolean}) {
// Make sure binding harmless values works. // Make sure binding harmless values works.
ci.ctxProp = 'some <p>text</p>'; ci.ctxProp = 'some <p>text</p>';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(e)).toEqual('some <p>text</p>'); expect(e.innerHTML).toEqual('some <p>text</p>');
ci.ctxProp = 'ha <script>evil()</script>'; ci.ctxProp = 'ha <script>evil()</script>';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(e)).toEqual('ha '); expect(e.innerHTML).toEqual('ha ');
ci.ctxProp = 'also <img src="x" onerror="evil()"> evil'; ci.ctxProp = 'also <img src="x" onerror="evil()"> evil';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(e)).toEqual('also <img src="x"> evil'); expect(e.innerHTML).toEqual('also <img src="x"> evil');
ci.ctxProp = 'also <iframe srcdoc="evil"></iframe> evil'; ci.ctxProp = 'also <iframe srcdoc="evil"></iframe> evil';
fixture.detectChanges(); fixture.detectChanges();
expect(getDOM().getInnerHTML(e)).toEqual('also evil'); expect(e.innerHTML).toEqual('also evil');
}); });
}); });
}); });

View File

@ -9,7 +9,6 @@
import {ElementRef} from '@angular/core'; import {ElementRef} from '@angular/core';
import {ChangeDetectorRef} from '@angular/core/src/change_detection/change_detection'; import {ChangeDetectorRef} from '@angular/core/src/change_detection/change_detection';
import {SpyObject} from '@angular/core/testing/src/testing_internal'; import {SpyObject} from '@angular/core/testing/src/testing_internal';
import {DomAdapter} from '@angular/platform-browser/src/dom/dom_adapter';
export class SpyChangeDetectorRef extends SpyObject { export class SpyChangeDetectorRef extends SpyObject {
constructor() { constructor() {
@ -24,7 +23,3 @@ export class SpyIterableDifferFactory extends SpyObject {}
export class SpyElementRef extends SpyObject { export class SpyElementRef extends SpyObject {
constructor() { super(ElementRef); } constructor() { super(ElementRef); }
} }
export class SpyDomAdapter extends SpyObject {
constructor() { super(DomAdapter); }
}

View File

@ -147,11 +147,9 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
isPrevented(evt: Event): boolean { isPrevented(evt: Event): boolean {
return evt.defaultPrevented || evt.returnValue != null && !evt.returnValue; return evt.defaultPrevented || evt.returnValue != null && !evt.returnValue;
} }
getInnerHTML(el: HTMLElement): string { return el.innerHTML; }
getTemplateContent(el: Node): Node|null { getTemplateContent(el: Node): Node|null {
return 'content' in el && this.isTemplateElement(el) ? (<any>el).content : null; return 'content' in el && this.isTemplateElement(el) ? (<any>el).content : null;
} }
getOuterHTML(el: HTMLElement): string { return el.outerHTML; }
nodeName(node: Node): string { return node.nodeName; } nodeName(node: Node): string { return node.nodeName; }
nodeValue(node: Node): string|null { return node.nodeValue; } nodeValue(node: Node): string|null { return node.nodeValue; }
type(node: HTMLInputElement): string { return node.type; } type(node: HTMLInputElement): string { return node.type; }

View File

@ -64,10 +64,8 @@ export abstract class DomAdapter {
abstract createEvent(eventType: string): any; abstract createEvent(eventType: string): any;
abstract preventDefault(evt: any): any; abstract preventDefault(evt: any): any;
abstract isPrevented(evt: any): boolean; abstract isPrevented(evt: any): boolean;
abstract getInnerHTML(el: any): string;
/** Returns content if el is a <template> element, null otherwise. */ /** Returns content if el is a <template> element, null otherwise. */
abstract getTemplateContent(el: any): any; abstract getTemplateContent(el: any): any;
abstract getOuterHTML(el: any): string;
abstract nodeName(node: any): string; abstract nodeName(node: any): string;
abstract nodeValue(node: any): string|null; abstract nodeValue(node: any): string|null;
abstract type(node: any): string; abstract type(node: any): string;

View File

@ -26,20 +26,20 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
it('should add existing styles to new hosts', () => { it('should add existing styles to new hosts', () => {
ssh.addStyles(['a {};']); ssh.addStyles(['a {};']);
ssh.addHost(someHost); ssh.addHost(someHost);
expect(getDOM().getInnerHTML(someHost)).toEqual('<style>a {};</style>'); expect(someHost.innerHTML).toEqual('<style>a {};</style>');
}); });
it('should add new styles to hosts', () => { it('should add new styles to hosts', () => {
ssh.addHost(someHost); ssh.addHost(someHost);
ssh.addStyles(['a {};']); ssh.addStyles(['a {};']);
expect(getDOM().getInnerHTML(someHost)).toEqual('<style>a {};</style>'); expect(someHost.innerHTML).toEqual('<style>a {};</style>');
}); });
it('should add styles only once to hosts', () => { it('should add styles only once to hosts', () => {
ssh.addStyles(['a {};']); ssh.addStyles(['a {};']);
ssh.addHost(someHost); ssh.addHost(someHost);
ssh.addStyles(['a {};']); ssh.addStyles(['a {};']);
expect(getDOM().getInnerHTML(someHost)).toEqual('<style>a {};</style>'); expect(someHost.innerHTML).toEqual('<style>a {};</style>');
}); });
it('should use the document head as default host', () => { it('should use the document head as default host', () => {
@ -50,10 +50,10 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
it('should remove style nodes on destroy', () => { it('should remove style nodes on destroy', () => {
ssh.addStyles(['a {};']); ssh.addStyles(['a {};']);
ssh.addHost(someHost); ssh.addHost(someHost);
expect(getDOM().getInnerHTML(someHost)).toEqual('<style>a {};</style>'); expect(someHost.innerHTML).toEqual('<style>a {};</style>');
ssh.ngOnDestroy(); ssh.ngOnDestroy();
expect(getDOM().getInnerHTML(someHost)).toEqual(''); expect(someHost.innerHTML).toEqual('');
}); });
}); });
} }

View File

@ -65,9 +65,7 @@ export class WorkerDomAdapter extends DomAdapter {
createEvent(eventType: string): any { throw 'not implemented'; } createEvent(eventType: string): any { throw 'not implemented'; }
preventDefault(evt: any) { throw 'not implemented'; } preventDefault(evt: any) { throw 'not implemented'; }
isPrevented(evt: any): boolean { throw 'not implemented'; } isPrevented(evt: any): boolean { throw 'not implemented'; }
getInnerHTML(el: any): string { throw 'not implemented'; }
getTemplateContent(el: any): any { throw 'not implemented'; } getTemplateContent(el: any): any { throw 'not implemented'; }
getOuterHTML(el: any): string { throw 'not implemented'; }
nodeName(node: any): string { throw 'not implemented'; } nodeName(node: any): string { throw 'not implemented'; }
nodeValue(node: any): string { throw 'not implemented'; } nodeValue(node: any): string { throw 'not implemented'; }
type(node: any): string { throw 'not implemented'; } type(node: any): string { throw 'not implemented'; }

View File

@ -137,7 +137,7 @@ let lastCreatedRenderer: Renderer2;
fixture.componentInstance.ctxBoolProp = true; fixture.componentInstance.ctxBoolProp = true;
fixture.detectChanges(); fixture.detectChanges();
const el = getRenderElement(fixture.nativeElement); const el = getRenderElement(fixture.nativeElement);
expect(getDOM().getInnerHTML(el)).toContain('"ng-reflect-ng-if": "true"'); expect(el.innerHTML).toContain('"ng-reflect-ng-if": "true"');
}); });
it('should add and remove fragments', () => { it('should add and remove fragments', () => {