/** * @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, Directive, ElementRef} from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {DomSanitizer, SafeStyle} from '@angular/platform-browser'; import {expect} from '@angular/platform-browser/testing/src/matchers'; describe('styling', () => { it('should render inline style and class attribute values on the element before a directive is instantiated', () => { @Component({ template: `
` }) class Cmp { } @Directive({selector: '[directive-expecting-styling]'}) class DirectiveExpectingStyling { constructor(elm: ElementRef) { const native = elm.nativeElement; native.setAttribute('data-captured-width', native.style.width); native.setAttribute('data-captured-classes', native.className); } } TestBed.configureTestingModule({declarations: [Cmp, DirectiveExpectingStyling]}); const fixture = TestBed.createComponent(Cmp); fixture.detectChanges(); const element = fixture.nativeElement.querySelector('div'); expect(element.style.width).toEqual('200px'); expect(element.getAttribute('data-captured-width')).toEqual('200px'); expect(element.className.trim()).toEqual('abc xyz'); expect(element.getAttribute('data-captured-classes')).toEqual('abc xyz'); }); it('should only render the same initial styling values once before a directive runs', () => { @Component({ template: `
` }) class Cmp { } @Directive({selector: '[directive-expecting-styling]'}) class DirectiveExpectingStyling { constructor(elm: ElementRef) { const native = elm.nativeElement; native.style.width = '300px'; native.classList.remove('abc'); } } TestBed.configureTestingModule({declarations: [Cmp, DirectiveExpectingStyling]}); const fixture = TestBed.createComponent(Cmp); fixture.detectChanges(); const element = fixture.nativeElement.querySelector('div'); expect(element.style.width).toEqual('300px'); expect(element.classList.contains('abc')).toBeFalsy(); }); it('should ensure that static classes are assigned to ng-container elements and picked up for content projection', () => { @Component({ template: ` outer inner ` }) class MyApp { } @Component({ selector: 'project', template: `
` }) class ProjectCmp { } TestBed.configureTestingModule({declarations: [MyApp, ProjectCmp]}); const fixture = TestBed.createComponent(MyApp); const element = fixture.nativeElement; fixture.detectChanges(); const inner = element.querySelector('.inner-area'); expect(inner.textContent.trim()).toEqual('inner'); const outer = element.querySelector('.outer-area'); expect(outer.textContent.trim()).toEqual('outer'); }); it('should do nothing for empty style bindings', () => { @Component({template: '
'}) class App { } TestBed.configureTestingModule({declarations: [App]}); const fixture = TestBed.createComponent(App); fixture.detectChanges(); expect(fixture.nativeElement.innerHTML).toBe('
'); }); it('should do nothing for empty class bindings', () => { @Component({template: '
'}) class App { } TestBed.configureTestingModule({declarations: [App]}); const fixture = TestBed.createComponent(App); fixture.detectChanges(); expect(fixture.nativeElement.innerHTML).toBe('
'); }); it('should be able to bind a SafeValue to backgroundImage', () => { @Component({template: '
'}) class Cmp { image !: SafeStyle; } TestBed.configureTestingModule({declarations: [Cmp]}); const fixture = TestBed.createComponent(Cmp); const sanitizer: DomSanitizer = TestBed.get(DomSanitizer); fixture.componentInstance.image = sanitizer.bypassSecurityTrustStyle('url("#test")'); fixture.detectChanges(); const div = fixture.nativeElement.querySelector('div') as HTMLDivElement; expect(div.style.backgroundImage).toBe('url("#test")'); }); });