Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test transclusion (ng-content) in Angular2?

i have a component to test as follow :

import {Component, OnInit, Input} from "@angular/core";

@Component({
    selector: 'column',
    template: '<ng-content></ng-content>',
    host: {
        '[class]': '"col col-" + width'
    }
})
export class ColumnComponent implements OnInit {

    @Input() public width: number;

    ngOnInit() {
        if (!this.width || this.width > 12 || this.width < 1) {
            this.width = 12;
        }
    }

}

i am not able to find an elegant way to test the <ng-content>. checked the documentations but not able to find a good way.

I thought having a test wrapper component will help. But the comp is not the one used TestContainerComponent so the test fails

  @Component({
        selector: 'test-container',
        template: `<column width="12">Hello</column>`
    })
    export class TestContainerComponent {
    }

    fdescribe(`Column`, () => {
        let comp: ColumnComponent;
        let fixture: ComponentFixture<ColumnComponent>;

        let testContainerComp: TestContainerComponent;
        let testContainerFixture: ComponentFixture<TestContainerComponent>;
        let testContainerDe: DebugElement;
        let testContainerEl: HTMLElement;

        beforeEach(async(() => {
            TestBed.configureTestingModule({
                declarations: [ColumnComponent, TestContainerComponent]
            }).compileComponents();
        }));

        beforeEach(() => {
            fixture = TestBed.createComponent(ColumnComponent);
            testContainerFixture = TestBed.createComponent(TestContainerComponent);
            comp = fixture.componentInstance;

            testContainerComp = testContainerFixture.componentInstance;
            testContainerDe = testContainerFixture.debugElement.query(By.css('column'));
            testContainerEl = testContainerDe.nativeElement.;

        });


        it(`Should have a width class as 'col-...' if width attribute set`, () => {
            comp.width = 6;
            testContainerFixture.detectChanges();
         expect(testContainerEl.classList.contains(`col-${comp.width}`)).toBeTruthy();
        });

    });

I guess i need a way to get the ColumnComponent component from the TestContainerComponent.

like image 700
semirturgay Avatar asked Feb 24 '17 13:02

semirturgay


People also ask

What is Ng-content content projection?

Content projection is a pattern in which you insert, or project, the content you want to use inside another component. For example, you could have a Card component that accepts content provided by another component.

How do you style content that was projected using NG-content?

If you want to style the projected content within <ng-content>, you can do so using :host and ::ng-deep to apply styling to all nested elements within the <contact> component.

How do you use NG-content?

The ng-content is used when we want to insert the content dynamically inside the component that helps to increase component reusability. Using ng-content we can pass content inside the component selector and when angular parses that content that appears at the place of ng-content.

What is Angular Transclusion?

Transclusion is a concept that let's you create a content-slot / ng-content inside your component. So if you have a child component with a content-slot / ng-content, the parent component that uses the child component can put whatever it wants inside the content-slot of the child component.


1 Answers

I think you can do it without using wrapper because there is way to get host element via calling:

fixture.elementRef.nativeElement;

so here is possible test:

fdescribe(`Column`, () => {
  let comp: ColumnComponent;
  let fixture: ComponentFixture<ColumnComponent>;

  let testContainerDe: DebugElement;
  let testContainerEl: HTMLElement;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ColumnComponent]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ColumnComponent);
    comp = fixture.componentInstance;
    testContainerEl = fixture.elementRef.nativeElement;
  });

  it(`Should have a width class as 'col-...' if width attribute set`, () => {
    comp.width = 6;
    fixture.detectChanges();
    expect(testContainerEl.classList.contains(`col-${comp.width}`)).toBeTruthy();
  });
});

Plunker Example

like image 193
yurzui Avatar answered Sep 18 '22 23:09

yurzui