From b1d45ee6d2e746c572203df7282a3610b6ba0e29 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Mon, 6 May 2019 12:45:09 -0700 Subject: [PATCH] test(ivy): move property and attribute tests to acceptance (#30321) - splits existing property acceptance tests into property_binding and property_interpolation - ports tests from render3 instructions tests to acceptance tests - removes redundant or unnecessary tests that are covered by existing acceptance tests :) PR Close #30321 --- .../core/test/acceptance/attributes_spec.ts | 100 ++ .../test/acceptance/property_binding_spec.ts | 138 +++ ...spec.ts => property_interpolation_spec.ts} | 140 ++- .../core/test/render3/instructions_spec.ts | 905 +----------------- 4 files changed, 339 insertions(+), 944 deletions(-) create mode 100644 packages/core/test/acceptance/attributes_spec.ts create mode 100644 packages/core/test/acceptance/property_binding_spec.ts rename packages/core/test/acceptance/{properties_spec.ts => property_interpolation_spec.ts} (67%) diff --git a/packages/core/test/acceptance/attributes_spec.ts b/packages/core/test/acceptance/attributes_spec.ts new file mode 100644 index 0000000000..d8946033a0 --- /dev/null +++ b/packages/core/test/acceptance/attributes_spec.ts @@ -0,0 +1,100 @@ +/** + * @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 {Component} from '@angular/core'; +import {TestBed} from '@angular/core/testing'; +import {By, DomSanitizer, SafeUrl} from '@angular/platform-browser'; + +describe('attribute creation', () => { + it('should create an element', () => { + @Component({ + template: `
`, + }) + class Comp { + } + + TestBed.configureTestingModule({declarations: [Comp]}); + const fixture = TestBed.createComponent(Comp); + fixture.detectChanges(); + const div = fixture.debugElement.query(By.css('div')).nativeElement; + expect(div.id).toEqual('test'); + expect(div.title).toEqual('Hello'); + }); + + it('should allow for setting xlink namespaced attributes', () => { + @Component({ + template: `
`, + }) + class Comp { + } + + TestBed.configureTestingModule({declarations: [Comp]}); + const fixture = TestBed.createComponent(Comp); + fixture.detectChanges(); + + + const div = fixture.debugElement.query(By.css('div')).nativeElement; + const attrs = div.attributes; + + expect(attrs['id'].name).toEqual('id'); + expect(attrs['id'].namespaceURI).toEqual(null); + expect(attrs['id'].value).toEqual('test'); + + expect(attrs['xlink:href'].name).toEqual('xlink:href'); + expect(attrs['xlink:href'].namespaceURI).toEqual('http://www.w3.org/1999/xlink'); + expect(attrs['xlink:href'].value).toEqual('bar'); + + expect(attrs['title'].name).toEqual('title'); + expect(attrs['title'].namespaceURI).toEqual(null); + expect(attrs['title'].value).toEqual('Hello'); + }); +}); + +describe('attribute binding', () => { + it('should set attribute values', () => { + @Component({ + template: ``, + }) + class Comp { + url = 'https://angular.io/robots.txt'; + } + + TestBed.configureTestingModule({declarations: [Comp]}); + const fixture = TestBed.createComponent(Comp); + fixture.detectChanges(); + + const a = fixture.debugElement.query(By.css('a')).nativeElement; + // NOTE: different browsers will add `//` into the URI. + expect(a.href).toEqual('https://angular.io/robots.txt'); + }); + + it('should sanitize attribute values', () => { + @Component({ + template: ``, + }) + class Comp { + badUrl: string|SafeUrl = 'javascript:true'; + } + + TestBed.configureTestingModule({declarations: [Comp]}); + const fixture = TestBed.createComponent(Comp); + fixture.detectChanges(); + + const a = fixture.debugElement.query(By.css('a')).nativeElement; + // NOTE: different browsers will add `//` into the URI. + expect(a.href.indexOf('unsafe:')).toBe(0); + + const domSanitizer: DomSanitizer = TestBed.get(DomSanitizer); + fixture.componentInstance.badUrl = + domSanitizer.bypassSecurityTrustUrl('javascript:alert("this is fine")'); + fixture.detectChanges(); + + // should not start with `unsafe:`. + expect(a.href.indexOf('unsafe:')).toBe(-1); + }); +}); diff --git a/packages/core/test/acceptance/property_binding_spec.ts b/packages/core/test/acceptance/property_binding_spec.ts new file mode 100644 index 0000000000..1bfe65e1b7 --- /dev/null +++ b/packages/core/test/acceptance/property_binding_spec.ts @@ -0,0 +1,138 @@ +/** + * @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 {Component, Input} from '@angular/core'; +import {TestBed} from '@angular/core/testing'; +import {By, DomSanitizer, SafeUrl} from '@angular/platform-browser'; + +describe('property bindings', () => { + it('should update bindings when value changes', () => { + @Component({ + template: ``, + }) + class Comp { + title = 'Hello'; + } + + TestBed.configureTestingModule({declarations: [Comp]}); + const fixture = TestBed.createComponent(Comp); + fixture.detectChanges(); + let a = fixture.debugElement.query(By.css('a')).nativeElement; + expect(a.title).toBe('Hello'); + + fixture.componentInstance.title = 'World'; + fixture.detectChanges(); + expect(a.title).toBe('World'); + }); + + it('should not update bindings when value does not change', () => { + @Component({ + template: ``, + }) + class Comp { + title = 'Hello'; + } + + TestBed.configureTestingModule({declarations: [Comp]}); + const fixture = TestBed.createComponent(Comp); + fixture.detectChanges(); + let a = fixture.debugElement.query(By.css('a')).nativeElement; + expect(a.title).toBe('Hello'); + + fixture.detectChanges(); + expect(a.title).toBe('Hello'); + }); + + it('should bind to properties whose names do not correspond to their attribute names', () => { + @Component({template: ''}) + class MyComp { + forValue?: string; + } + + TestBed.configureTestingModule({declarations: [MyComp]}); + const fixture = TestBed.createComponent(MyComp); + const labelNode = fixture.debugElement.query(By.css('label')); + + fixture.componentInstance.forValue = 'some-input'; + fixture.detectChanges(); + + expect(labelNode.nativeElement.getAttribute('for')).toBe('some-input'); + + fixture.componentInstance.forValue = 'some-textarea'; + fixture.detectChanges(); + + expect(labelNode.nativeElement.getAttribute('for')).toBe('some-textarea'); + }); + + it('should not map properties whose names do not correspond to their attribute names, ' + + 'if they correspond to inputs', + () => { + + @Component({template: '', selector: 'my-comp'}) + class MyComp { + @Input() for !:string; + } + + @Component({template: ''}) + class App { + forValue?: string; + } + + TestBed.configureTestingModule({declarations: [App, MyComp]}); + const fixture = TestBed.createComponent(App); + const myCompNode = fixture.debugElement.query(By.directive(MyComp)); + fixture.componentInstance.forValue = 'hello'; + fixture.detectChanges(); + expect(myCompNode.nativeElement.getAttribute('for')).toBeFalsy(); + expect(myCompNode.componentInstance.for).toBe('hello'); + + fixture.componentInstance.forValue = 'hej'; + fixture.detectChanges(); + expect(myCompNode.nativeElement.getAttribute('for')).toBeFalsy(); + expect(myCompNode.componentInstance.for).toBe('hej'); + }); + + it('should use the sanitizer in bound properties', () => { + @Component({ + template: ` + + ` + }) + class App { + url: string|SafeUrl = 'javascript:alert("haha, I am taking over your computer!!!");'; + } + + TestBed.configureTestingModule({declarations: [App]}); + const fixture = TestBed.createComponent(App); + fixture.detectChanges(); + const a = fixture.nativeElement.querySelector('a'); + + expect(a.href.indexOf('unsafe:')).toBe(0); + + const domSanitzer: DomSanitizer = TestBed.get(DomSanitizer); + fixture.componentInstance.url = + domSanitzer.bypassSecurityTrustUrl('javascript:alert("the developer wanted this");'); + fixture.detectChanges(); + + expect(a.href.indexOf('unsafe:')).toBe(-1); + }); + + it('should not stringify non-string values', () => { + @Component({ + template: ``, + }) + class Comp { + isRequired = false; + } + + TestBed.configureTestingModule({declarations: [Comp]}); + const fixture = TestBed.createComponent(Comp); + fixture.detectChanges(); + + expect(fixture.debugElement.query(By.css('input')).nativeElement.required).toBe(false); + }); +}); diff --git a/packages/core/test/acceptance/properties_spec.ts b/packages/core/test/acceptance/property_interpolation_spec.ts similarity index 67% rename from packages/core/test/acceptance/properties_spec.ts rename to packages/core/test/acceptance/property_interpolation_spec.ts index d7fa008672..c360db6d53 100644 --- a/packages/core/test/acceptance/properties_spec.ts +++ b/packages/core/test/acceptance/property_interpolation_spec.ts @@ -5,82 +5,12 @@ * 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 {Component, Input} from '@angular/core'; +import {Component} from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; -import {expect} from '@angular/platform-browser/testing/src/matchers'; import {of } from 'rxjs'; -describe('property instructions', () => { - it('should bind to properties whose names do not correspond to their attribute names', () => { - @Component({template: ''}) - class MyComp { - forValue?: string; - } - - TestBed.configureTestingModule({declarations: [MyComp]}); - const fixture = TestBed.createComponent(MyComp); - const labelNode = fixture.debugElement.query(By.css('label')); - - fixture.componentInstance.forValue = 'some-input'; - fixture.detectChanges(); - - expect(labelNode.nativeElement.getAttribute('for')).toBe('some-input'); - - fixture.componentInstance.forValue = 'some-textarea'; - fixture.detectChanges(); - - expect(labelNode.nativeElement.getAttribute('for')).toBe('some-textarea'); - }); - - it('should not allow unsanitary urls in bound properties', () => { - @Component({ - template: ` - - ` - }) - class App { - naughty = 'javascript:alert("haha, I am taking over your computer!!!");'; - } - - TestBed.configureTestingModule({declarations: [App]}); - const fixture = TestBed.createComponent(App); - fixture.detectChanges(); - const img = fixture.nativeElement.querySelector('img'); - - expect(img.src.indexOf('unsafe:')).toBe(0); - }); - - - it('should not map properties whose names do not correspond to their attribute names, ' + - 'if they correspond to inputs', - () => { - - @Component({template: '', selector: 'my-comp'}) - class MyComp { - @Input() for !:string; - } - - @Component({template: ''}) - class App { - forValue?: string; - } - - TestBed.configureTestingModule({declarations: [App, MyComp]}); - const fixture = TestBed.createComponent(App); - const myCompNode = fixture.debugElement.query(By.directive(MyComp)); - fixture.componentInstance.forValue = 'hello'; - fixture.detectChanges(); - expect(myCompNode.nativeElement.getAttribute('for')).toBeFalsy(); - expect(myCompNode.componentInstance.for).toBe('hello'); - - fixture.componentInstance.forValue = 'hej'; - fixture.detectChanges(); - expect(myCompNode.nativeElement.getAttribute('for')).toBeFalsy(); - expect(myCompNode.componentInstance.for).toBe('hej'); - }); - +describe('property interpolation', () => { it('should handle all flavors of interpolated properties', () => { @Component({ template: ` @@ -230,4 +160,70 @@ describe('property instructions', () => { .toEqual( `http://g.com/?one=1&two=2&three=3&four=4&five=5&six=6&seven=7&eight=8&nine=9&ten=10`); }); + + it('should support the chained use cases of propertyInterpolate instructions', () => { + // The below *just happens* to have two attributes in a row that have the same interpolation + // count. + @Component({ + template: ` + a{{one}}b{{two}}c{{three}}d{{four}}e{{five}}f{{six}}g{{seven}}h{{eight}}i{{nine}}j + a{{one}}b{{two}}c{{three}}d{{four}}e{{five}}f{{six}}g{{seven}}h{{eight}}i + a{{one}}b{{two}}c{{three}}d{{four}}e{{five}}f{{six}}g{{seven}}h + a{{one}}b{{two}}c{{three}}d{{four}}e{{five}}f{{six}}g + a{{one}}b{{two}}c{{three}}d{{four}}e{{five}}f + a{{one}}b{{two}}c{{three}}d{{four}}e + a{{one}}b{{two}}c{{three}}d + a{{one}}b{{two}}c + a{{one}}b + {{one}} + ` + }) + class AppComp { + one = 1; + two = 2; + three = 3; + four = 4; + five = 5; + six = 6; + seven = 7; + eight = 8; + nine = 9; + } + + TestBed.configureTestingModule({declarations: [AppComp]}); + const fixture = TestBed.createComponent(AppComp); + fixture.detectChanges(); + + const titles = Array.from(fixture.nativeElement.querySelectorAll('img[title]')) + .map((img: HTMLImageElement) => img.title); + + expect(titles).toEqual([ + 'a1b2c3d4e5f6g7h8i9j', + 'a1b2c3d4e5f6g7h8i', + 'a1b2c3d4e5f6g7h', + 'a1b2c3d4e5f6g', + 'a1b2c3d4e5f', + 'a1b2c3d4e', + 'a1b2c3d', + 'a1b2c', + 'a1b', + '1', + ]); + + const others = Array.from(fixture.nativeElement.querySelectorAll('img[alt]')) + .map((img: HTMLImageElement) => img.alt); + + expect(others).toEqual([ + 'a1b2c3d4e5f6g7h8i9j', + 'a1b2c3d4e5f6g7h8i', + 'a1b2c3d4e5f6g7h', + 'a1b2c3d4e5f6g', + 'a1b2c3d4e5f', + 'a1b2c3d4e', + 'a1b2c3d', + 'a1b2c', + 'a1b', + '1', + ]); + }); }); diff --git a/packages/core/test/render3/instructions_spec.ts b/packages/core/test/render3/instructions_spec.ts index a5c35e778b..cc75beec31 100644 --- a/packages/core/test/render3/instructions_spec.ts +++ b/packages/core/test/render3/instructions_spec.ts @@ -7,7 +7,6 @@ */ import {NgForOfContext} from '@angular/common'; -import {ɵɵpropertyInterpolate, ɵɵpropertyInterpolate1, ɵɵpropertyInterpolate2, ɵɵpropertyInterpolate3, ɵɵpropertyInterpolate4, ɵɵpropertyInterpolate5, ɵɵpropertyInterpolate6, ɵɵpropertyInterpolate7, ɵɵpropertyInterpolate8, ɵɵpropertyInterpolateV} from '@angular/core/src/render3/instructions/all'; import {ɵɵdefineComponent} from '../../src/render3/definition'; import {RenderFlags, ɵɵbind, ɵɵclassMap, ɵɵelement, ɵɵelementAttribute, ɵɵelementEnd, ɵɵelementProperty, ɵɵelementStart, ɵɵinterpolation1, ɵɵproperty, ɵɵselect, ɵɵstyleMap, ɵɵstyleProp, ɵɵstyling, ɵɵstylingApply, ɵɵtemplate, ɵɵtext, ɵɵtextBinding} from '../../src/render3/index'; @@ -45,8 +44,18 @@ describe('instructions', () => { function createScript() { ɵɵelement(0, 'script'); } + describe('ɵɵselect', () => { + it('should error in DevMode if index is out of range', () => { + // Only one constant added, meaning only index `0` is valid. + const t = new TemplateFixture(createDiv, () => {}, 1, 0); + expect(() => { t.update(() => { ɵɵselect(-1); }); }).toThrow(); + expect(() => { t.update(() => { ɵɵselect(1); }); }).toThrow(); + expect(() => { t.update(() => { ɵɵselect(0); }); }).not.toThrow(); + }); + }); + describe('bind', () => { - it('should update bindings when value changes', () => { + it('should update bindings when value changes with the correct perf counters', () => { const t = new TemplateFixture(createAnchor, () => {}, 1, 1); t.update(() => ɵɵelementProperty(0, 'title', ɵɵbind('Hello'))); @@ -63,27 +72,28 @@ describe('instructions', () => { }); }); - it('should not update bindings when value does not change', () => { - const idempotentUpdate = () => ɵɵelementProperty(0, 'title', ɵɵbind('Hello')); - const t = new TemplateFixture(createAnchor, idempotentUpdate, 1, 1); + it('should not update bindings when value does not change, with the correct perf counters', + () => { + const idempotentUpdate = () => ɵɵelementProperty(0, 'title', ɵɵbind('Hello')); + const t = new TemplateFixture(createAnchor, idempotentUpdate, 1, 1); - t.update(); - expect(t.html).toEqual(''); + t.update(); + expect(t.html).toEqual(''); - t.update(); - expect(t.html).toEqual(''); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for hostElement + 1 for the template under test - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 1 - }); - }); + t.update(); + expect(t.html).toEqual(''); + expect(ngDevMode).toHaveProperties({ + firstTemplatePass: 1, + tNode: 2, // 1 for hostElement + 1 for the template under test + tView: 2, // 1 for rootView + 1 for the template view + rendererCreateElement: 1, + rendererSetProperty: 1 + }); + }); }); describe('element', () => { - it('should create an element', () => { + it('should create an element with the correct perf counters', () => { const t = new TemplateFixture(() => { ɵɵelement(0, 'div', ['id', 'test', 'title', 'Hello']); }, () => {}, 1); @@ -98,47 +108,6 @@ describe('instructions', () => { rendererCreateElement: 1, }); }); - - it('should allow setting namespaced attributes', () => { - const t = new TemplateFixture(() => { - ɵɵelement(0, 'div', [ - // id="test" - 'id', - 'test', - // test:foo="bar" - AttributeMarker.NamespaceURI, - 'http://someuri.com/2018/test', - 'test:foo', - 'bar', - // title="Hello" - 'title', - 'Hello', - ]); - }, () => {}, 1); - - const div = (t.hostElement as HTMLElement).querySelector('div') !; - const attrs: any = div.attributes; - - expect(attrs['id'].name).toEqual('id'); - expect(attrs['id'].namespaceURI).toEqual(null); - expect(attrs['id'].value).toEqual('test'); - - expect(attrs['test:foo'].name).toEqual('test:foo'); - expect(attrs['test:foo'].namespaceURI).toEqual('http://someuri.com/2018/test'); - expect(attrs['test:foo'].value).toEqual('bar'); - - expect(attrs['title'].name).toEqual('title'); - expect(attrs['title'].namespaceURI).toEqual(null); - expect(attrs['title'].value).toEqual('Hello'); - - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetAttribute: 3 - }); - }); }); describe('elementAttribute', () => { @@ -162,41 +131,12 @@ describe('instructions', () => { }); }); - describe('ɵɵselect', () => { - it('should error in DevMode if index is out of range', () => { - // Only one constant added, meaning only index `0` is valid. - const t = new TemplateFixture(createDiv, () => {}, 1, 0); - expect(() => { t.update(() => { ɵɵselect(-1); }); }).toThrow(); - expect(() => { t.update(() => { ɵɵselect(1); }); }).toThrow(); - expect(() => { t.update(() => { ɵɵselect(0); }); }).not.toThrow(); - }); - }); - describe('property', () => { - // TODO(benlesh): Replace with TestBed tests once the instruction is being generated. - it('should set properties of the ɵɵselected element', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 1); - t.update(() => { - ɵɵselect(0); - ɵɵproperty('title', 'one'); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵproperty('title', 'two'); - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - // TODO(benlesh): Replace with TestBed tests once the instruction is being generated. + /** + * TODO: We need to replace this with an acceptance test, but for right now, + * this is the only test that ensures chaining works, since code generation + * is not producing chained instructions yet. + */ it('should chain', () => { //
const t = new TemplateFixture(createDiv, () => {}, 1, 2); @@ -219,29 +159,6 @@ describe('instructions', () => { }); }); - // TODO(benlesh): Replace with TestBed tests once the instruction is being generated. - it('should diff value changes', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 2); - t.update(() => { - ɵɵselect(0); - ɵɵproperty('title', 'one')('accessKey', 'A'); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵproperty('title', 'two')('accessKey', 'A'); // Notice: only changing the title. - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 3, - }); - }); - it('should error in dev mode if ɵɵselect was not called prior', () => { const t = new TemplateFixture(createDiv, () => {}, 1, 1); expect(() => { t.update(() => { ɵɵproperty('title', 'test'); }); }).toThrow(); @@ -254,762 +171,6 @@ describe('instructions', () => { }); }); - /** - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * TODO: REMOVE ALL OF THESE TemplateFixture TESTS FOR TestBed TESTS AFTER COMPILER IS UPDATED - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - describe('ɵɵpropertyInterpolate instructions', () => { - describe('ɵɵpropertyInterpolate', () => { - it('should interpolate one value', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 1); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate('title', 123); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate('title', 'abc'); - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - it('should chain', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 2); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate('title', 123)('accessKey', 'A'); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate('title', 'abc')('accessKey', 'B'); - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 4, - }); - }); - - it('should error if called without ɵɵselect called first', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 1); - expect(() => { t.update(() => { ɵɵpropertyInterpolate('title', 123); }); }).toThrow(); - expect(() => { - ɵɵselect(0); - t.update(() => { ɵɵpropertyInterpolate('title', 123); }); - }).not.toThrow(); - }); - }); - - describe('ɵɵpropertyInterpolate1', () => { - it('should interpolate one value', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 1); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate1('title', 'start', 123, 'end'); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate1('title', 'start', 'abc', 'end'); - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - it('should chain', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 2); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate1('title', 'start', 123, 'end')('accessKey', 'start', 'A', 'end'); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate1('title', 'start', 'abc', 'end')('accessKey', 'start', 'B', 'end'); - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 4, - }); - }); - - it('should error if called without ɵɵselect called first', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 1); - expect(() => { - t.update(() => { ɵɵpropertyInterpolate1('title', 'start', 'whatever', 'end'); }); - }).toThrow(); - expect(() => { - ɵɵselect(0); - t.update(() => { ɵɵpropertyInterpolate1('title', 'start', 'whatever', 'end'); }); - }).not.toThrow(); - }); - }); - - describe('ɵɵpropertyInterpolate2', () => { - it('should interpolate two values', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 2); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate2('title', 'start: ', 0, ', 1: ', 1, ', end'); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate2('title', 'start: ', 'A', ', 1: ', 'B', ', end'); - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - it('should chain', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 4); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate2('title', 'start: ', 0, ', 1: ', 1, ', end')( - 'accessKey', 'start: ', 0, ', 1: ', 1, ', end'); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate2('title', 'start: ', 'A', ', 1: ', 'B', ', end')( - 'accessKey', 'start: ', 'A', ', 1: ', 'B', ', end'); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 4, - }); - }); - - it('should error if called without ɵɵselect called first', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 2); - expect(() => { - t.update(() => { ɵɵpropertyInterpolate2('title', '', '', '', '', ''); }); - }).toThrow(); - expect(() => { - ɵɵselect(0); - t.update(() => { ɵɵpropertyInterpolate2('title', '', '', '', '', ''); }); - }).not.toThrow(); - }); - }); - - describe('ɵɵpropertyInterpolate3', () => { - it('should interpolate three values', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 3); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate3('title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', end'); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate3('title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', end'); - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - it('should chain', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 6); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate3('title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', end')( - 'accessKey', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', end'); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate3('title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', end')( - 'accessKey', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', end'); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 4, - }); - }); - - it('should error if called without ɵɵselect called first', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 3); - expect(() => { - t.update(() => { ɵɵpropertyInterpolate3('title', '', '', '', '', '', '', ''); }); - }).toThrow(); - expect(() => { - ɵɵselect(0); - t.update(() => { ɵɵpropertyInterpolate3('title', '', '', '', '', '', '', ''); }); - }).not.toThrow(); - }); - }); - - - describe('ɵɵpropertyInterpolate4', () => { - it('should interpolate four values', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 4); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate4( - 'title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', end'); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate4( - 'title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', end'); - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - it('should chain', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 8); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate4( - 'title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', end')( - 'accessKey', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', end'); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate4( - 'title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', end')( - 'accessKey', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', end'); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 4, - }); - }); - - it('should error if called without ɵɵselect called first', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 4); - expect(() => { - t.update(() => { ɵɵpropertyInterpolate4('title', '', '', '', '', '', '', '', '', ''); }); - }).toThrow(); - expect(() => { - ɵɵselect(0); - t.update(() => { ɵɵpropertyInterpolate4('title', '', '', '', '', '', '', '', '', ''); }); - }).not.toThrow(); - }); - }); - - describe('ɵɵpropertyInterpolate5', () => { - it('should interpolate five values', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 5); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate5( - 'title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', end'); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate5( - 'title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', end'); - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - it('should chain', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 10); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate5( - 'title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', end')( - 'accessKey', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', end'); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate5( - 'title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', end')( - 'accessKey', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', end'); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 4, - }); - }); - - it('should error if called without ɵɵselect called first', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 5); - expect(() => { - t.update(() => { - ɵɵpropertyInterpolate5('title', '', '', '', '', '', '', '', '', '', '', ''); - }); - }).toThrow(); - expect(() => { - ɵɵselect(0); - t.update(() => { - ɵɵpropertyInterpolate5('title', '', '', '', '', '', '', '', '', '', '', ''); - }); - }).not.toThrow(); - }); - }); - - describe('ɵɵpropertyInterpolate6', () => { - it('should interpolate six values', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 6); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate6( - 'title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, - ', end'); - }); - expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate6( - 'title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', 5: ', 'F', ', end'); - }); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - it('should chain', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 12); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate6( - 'title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, - ', end')( - 'accessKey', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, - ', end'); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate6( - 'title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', 5: ', 'F', ', end')( - 'accessKey', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', 5: ', 'F', ', end'); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 4, - }); - }); - - it('should error if called without ɵɵselect called first', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 6); - expect(() => { - t.update(() => { - ɵɵpropertyInterpolate6('title', '', '', '', '', '', '', '', '', '', '', '', '', ''); - }); - }).toThrow(); - expect(() => { - ɵɵselect(0); - t.update(() => { - ɵɵpropertyInterpolate6('title', '', '', '', '', '', '', '', '', '', '', '', '', ''); - }); - }).not.toThrow(); - }); - }); - - describe('ɵɵpropertyInterpolate7', () => { - it('should interpolate seven values', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 7); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate7( - 'title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, - ', 6: ', 6, ', end'); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate7( - 'title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', 5: ', 'F', ', 6: ', 'G', ', end'); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - it('should chain', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 14); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate7( - 'title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, - ', 6: ', 6, ', end')( - 'accessKey', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, - ', 6: ', 6, ', end'); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate7( - 'title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', 5: ', 'F', ', 6: ', 'G', ', end')( - 'accessKey', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', 5: ', 'F', ', 6: ', 'G', ', end'); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 4, - }); - }); - - it('should error if called without ɵɵselect called first', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 7); - expect(() => { - t.update(() => { - ɵɵpropertyInterpolate7( - 'title', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''); - }); - }).toThrow(); - expect(() => { - ɵɵselect(0); - t.update(() => { - ɵɵpropertyInterpolate7( - 'title', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''); - }); - }).not.toThrow(); - }); - }); - - describe('ɵɵpropertyInterpolate8', () => { - it('should interpolate eight values', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 8); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate8( - 'title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, - ', 6: ', 6, ', 7: ', 7, ', end'); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate8( - 'title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', 5: ', 'F', ', 6: ', 'G', ', 7: ', 'H', ', end'); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - it('should chain', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 16); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate8( - 'title', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, - ', 6: ', 6, ', 7: ', 7, ', end')( - 'accessKey', 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, - ', 6: ', 6, ', 7: ', 7, ', end'); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolate8( - 'title', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', 5: ', 'F', ', 6: ', 'G', ', 7: ', 'H', ', end')( - 'accessKey', 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', - ', 5: ', 'F', ', 6: ', 'G', ', 7: ', 'H', ', end'); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 4, - }); - }); - - it('should error if called without ɵɵselect called first', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 8); - expect(() => { - t.update(() => { - ɵɵpropertyInterpolate8( - 'title', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''); - }); - }).toThrow(); - expect(() => { - ɵɵselect(0); - t.update(() => { - ɵɵpropertyInterpolate8( - 'title', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''); - }); - }).not.toThrow(); - }); - }); - - - describe('ɵɵpropertyInterpolateV', () => { - it('should interpolate eight or more values', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 9); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolateV('title', [ - 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, ', 6: ', 6, - ', 7: ', 7, ', 8: ', 8, ', end' - ]); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolateV('title', [ - 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', ', 5: ', 'F', - ', 6: ', 'G', ', 7: ', 'H', ', 8: ', 'I', ', end' - ]); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 2, - }); - }); - - it('should chain', () => { - //
- const t = new TemplateFixture(createDiv, () => {}, 1, 18); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolateV( - 'title', - [ - 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, ', 6: ', - 6, ', 7: ', 7, ', 8: ', 8, ', end' - ])( - 'accessKey', [ - 'start: ', 0, ', 1: ', 1, ', 2: ', 2, ', 3: ', 3, ', 4: ', 4, ', 5: ', 5, ', 6: ', - 6, ', 7: ', 7, ', 8: ', 8, ', end' - ]); - }); - expect(t.html).toEqual( - '
'); - t.update(() => { - ɵɵselect(0); - ɵɵpropertyInterpolateV( - 'title', - [ - 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', ', 5: ', - 'F', ', 6: ', 'G', ', 7: ', 'H', ', 8: ', 'I', ', end' - ])( - 'accessKey', [ - 'start: ', 'A', ', 1: ', 'B', ', 2: ', 'C', ', 3: ', 'D', ', 4: ', 'E', ', 5: ', - 'F', ', 6: ', 'G', ', 7: ', 'H', ', 8: ', 'I', ', end' - ]); - }); - expect(t.html).toEqual( - '
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 4, - }); - }); - - it('should error if called without ɵɵselect called first', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 9); - expect(() => { - t.update(() => { - ɵɵpropertyInterpolateV( - 'title', - ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']); - }); - }).toThrow(); - expect(() => { - ɵɵselect(0); - t.update(() => { - ɵɵpropertyInterpolateV( - 'title', - ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']); - }); - }).not.toThrow(); - }); - }); - }); - - describe('elementProperty', () => { - it('should use sanitizer function when available', () => { - const t = new TemplateFixture(createDiv, () => {}, 1); - - t.update(() => ɵɵelementProperty(0, 'title', 'javascript:true', ɵɵsanitizeUrl)); - expect(t.html).toEqual('
'); - - t.update( - () => ɵɵelementProperty( - 0, 'title', bypassSanitizationTrustUrl('javascript:false'), ɵɵsanitizeUrl)); - expect(t.html).toEqual('
'); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - }); - }); - - it('should not stringify non string values', () => { - const t = new TemplateFixture(() => { ɵɵelement(0, 'input'); }, () => {}, 1); - - // Note: don't use 'hidden' here because IE10 does not support the hidden property - t.update(() => ɵɵelementProperty(0, 'required', false)); - // The required property would be true if `false` was stringified into `"false"`. - expect((t.hostElement as HTMLElement).querySelector('input') !.required).toEqual(false); - expect(ngDevMode).toHaveProperties({ - firstTemplatePass: 1, - tNode: 2, // 1 for div, 1 for host element - tView: 2, // 1 for rootView + 1 for the template view - rendererCreateElement: 1, - rendererSetProperty: 1 - }); - }); - }); - describe('styleProp', () => { it('should automatically sanitize unless a bypass operation is applied', () => { const t = new TemplateFixture(() => {