Skip to content

Commit

Permalink
feat(components): add support for entry components
Browse files Browse the repository at this point in the history
you can now pass entryComponents to spectator

#6
  • Loading branch information
NetanelBasal committed Apr 5, 2018
1 parent 06d9c53 commit 8ba6870
Show file tree
Hide file tree
Showing 12 changed files with 125 additions and 31 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
"@commitlint/config-angular": "^6.1.3",
"@commitlint/config-conventional": "^6.1.3",
"@types/jasmine": "^2.8.6",
"@types/jasminewd2": "~2.0.2",
"@types/node": "~6.0.60",
"all-contributors-cli": "^4.11.1",
"codelyzer": "^4.0.1",
Expand Down
21 changes: 1 addition & 20 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,20 +1 @@
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>
<ul>
<li>
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
</li>
<li>
<h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>
</li>
<li>
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
</li>
</ul>

<app-consume-dynamic></app-consume-dynamic>
7 changes: 6 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ import { ButtonComponent } from "./button/button.component";
import { HttpClientModule } from "@angular/common/http";
import { HighlightDirective } from "./highlight.directive";
import { CalcComponent } from "./calc/calc.component";
import { DynamicComponent } from "./dynamic/dynamic.component";
import { ConsumeDynamicComponent } from "./consum-dynamic/consume-dynamic.component";

@NgModule({
declarations: [
AppComponent,
ZippyComponent,
ButtonComponent,
HighlightDirective,
CalcComponent
CalcComponent,
DynamicComponent,
ConsumeDynamicComponent
],
entryComponents: [DynamicComponent],
imports: [BrowserModule, HttpClientModule],
providers: [],
bootstrap: [AppComponent]
Expand Down
26 changes: 26 additions & 0 deletions src/app/consum-dynamic/consume-dynamic.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
createHostComponentFactory,
SpectatorWithHost
} from "../../lib/src/host";
import { ConsumeDynamicComponent } from "./consume-dynamic.component";
import { DynamicComponent } from "../dynamic/dynamic.component";

fdescribe("ConsumeDynamicComponent", () => {
let host: SpectatorWithHost<ConsumeDynamicComponent>;

const createHost = createHostComponentFactory({
declarations: [DynamicComponent],
entryComponents: [DynamicComponent],
component: ConsumeDynamicComponent
});

it("should work", () => {
host = createHost(`<app-consume-dynamic></app-consume-dynamic>`);
expect(host.component).toBeDefined();
});

it("should render the dynamic component", function() {
host = createHost(`<app-consume-dynamic></app-consume-dynamic>`);
expect(host.queryHost(".dynamic")).toHaveText("dynamic works!");
});
});
28 changes: 28 additions & 0 deletions src/app/consum-dynamic/consume-dynamic.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {
Component,
ComponentFactoryResolver,
OnInit,
ViewContainerRef
} from "@angular/core";
import { DynamicComponent } from "../dynamic/dynamic.component";

@Component({
selector: "app-consume-dynamic",
template: `
<p>
consume-dynamic works!
</p>
`,
styles: []
})
export class ConsumeDynamicComponent implements OnInit {
constructor(
private resolver: ComponentFactoryResolver,
private ref: ViewContainerRef
) {}

ngOnInit() {
const factory = this.resolver.resolveComponentFactory(DynamicComponent);
this.ref.createComponent(factory);
}
}
16 changes: 16 additions & 0 deletions src/app/dynamic/dynamic.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Component, OnInit } from "@angular/core";

@Component({
selector: "app-dynamic",
template: `
<p class="dynamic">
dynamic works!
</p>
`,
styles: []
})
export class DynamicComponent implements OnInit {
constructor() {}

ngOnInit() {}
}
2 changes: 0 additions & 2 deletions src/index.ts

This file was deleted.

12 changes: 8 additions & 4 deletions src/lib/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@ export type SpectatorOptions<T = any, H = HostComponent> = TestModuleMetadata &
shallow?: boolean;
disableAnimations?: boolean;
host?: Type<H>;
entryComponents?: any[];
};

const defaultOptions: SpectatorOptions<any, any> = {
disableAnimations: true,
shallow: false,
host: HostComponent
host: HostComponent,
entryComponents: []
};

export function initialModule<T, C = HostComponent>(options: SpectatorOptions<T, C> | Type<T>, withHost = false) {
const merged = Object.assign({}, defaultOptions, options);
let moduleMetadata: TestModuleMetadata;
let moduleMetadata: TestModuleMetadata & { entryComponents: any[] };
let component;
let host;

Expand All @@ -41,7 +43,8 @@ export function initialModule<T, C = HostComponent>(options: SpectatorOptions<T,
declarations: [component, withHost ? host : []],
imports: [NoopAnimationsModule],
schemas: [],
providers: []
providers: [],
entryComponents: []
};
} else {
component = merged.component;
Expand All @@ -51,7 +54,8 @@ export function initialModule<T, C = HostComponent>(options: SpectatorOptions<T,
declarations: [component, withHost ? host : [], ...(merged.declarations || [])],
imports: [merged.disableAnimations ? NoopAnimationsModule : [], ...(merged.imports || [])],
schemas: [merged.shallow ? NO_ERRORS_SCHEMA : []],
providers: [...(merged.providers || [])]
providers: [...(merged.providers || [])],
entryComponents: [options.entryComponents]
};
}

Expand Down
38 changes: 38 additions & 0 deletions src/lib/src/host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { Spectator } from './internals';
import * as customMatchers from './matchers';
import { By } from '@angular/platform-browser';
import { HostComponent, initialModule, SpectatorOptions } from './config';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
import { DynamicComponent } from '../../app/dynamic/dynamic.component';

export class SpectatorWithHost<C, H = HostComponent> extends Spectator<C> {
hostComponent: H;
Expand All @@ -28,6 +30,37 @@ export class SpectatorWithHost<C, H = HostComponent> extends Spectator<C> {
byDirective<T>(directive: Type<any>): DebugElement {
return this.hostDebugElement.query(By.directive(directive));
}

/**
*
* @param {string} selector
* @param {true} debugElement
* @returns {DebugElement}
*/
queryHost(selector: string, debugElement: true): DebugElement;
queryHost(selector: string, debugElement?: false): Element;
queryHost(selector: string, debugElement = false): Element | DebugElement {
if (debugElement) {
return this.hostDebugElement.query(By.css(selector));
}

return this.hostElement.querySelector(selector);
}

/**
* Query a DOM elements from the tested element
* @param selector
* @returns {any}
*/
queryAllHost(selector: string, debugElement: true): DebugElement[];
queryAllHost(selector: string, debugElement?: false): NodeListOf<Element>;
queryAllHost(selector: string, debugElement = false): NodeListOf<Element> | DebugElement[] {
if (debugElement) {
return this.debugElement.queryAll(By.css(selector));
}

return this.element.querySelectorAll(selector);
}
}

export function createHostComponentFactory<C, H = HostComponent>(component: Type<C>): (template: string, detectChanges?: boolean, complexInputs?: Partial<C>) => SpectatorWithHost<C, H>;
Expand All @@ -45,6 +78,11 @@ export function createHostComponentFactory<C, H = HostComponent>(options: Specta

return (template: string, detectChanges = true, complexInputs: Partial<C> = {}) => {
TestBed.overrideComponent(host, { set: { template: template } });
TestBed.overrideModule(BrowserDynamicTestingModule, {
set: {
entryComponents: moduleMetadata.entryComponents
}
});
const spectatorWithHost = new SpectatorWithHost<C, H>();
spectatorWithHost.hostFixture = TestBed.createComponent(host);

Expand Down
1 change: 0 additions & 1 deletion src/lib/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
],
"declaration": true,
"outDir": "./dist",
"noEmitOnError": false,
"typeRoots": [
"./node_modules/@types",
"src"
Expand Down
3 changes: 1 addition & 2 deletions src/tsconfig.app.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
"compilerOptions": {
"outDir": "../out-tsc/app",
"baseUrl": "./",
"module": "es2015",
"types": []
"module": "es2015"
},
"exclude": [
"test.ts",
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"noEmitOnError": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
Expand Down

0 comments on commit 8ba6870

Please sign in to comment.