import { Component } from "ng-forward";
import { TestComponentBuilder, ngClass } from 'ng-forward/cjs/testing/test-component-builder';
import { INgForwardJQuery } from "ng-forward/cjs/util/jqlite-extensions";
import { ComponentFixture } from 'ng-forward/cjs/testing/test-component-builder';
/**
* @ngdoc object
* @name spec.ComponentTestHelper
* @description
*
* Helper class for creating tests. It encapsulates the TestComponentBuilder initialization,
* allowing the test to be DRY. To use, one must declare a beforeEach function in the
* test, and inside construct this object like:
*
*
* let helper = let helper : ComponentTestHelper;
* beforeEach( (done) => {
* helper = new ComponentTestHelper(cls, tcb);
* }
*
*/
export class ComponentTestHelper {
/**
* @ngdoc property
* @name mockComponent
* @propertyOf spec.ComponentTestHelper
* @description
* The component we are mocking.
*/
mockComponent: ngClass;
/**
* @ngdoc property
* @name tcb
* @propertyOf spec.ComponentTestHelper
* @description
* The NgForward TestComponentBuilder
*/
tcb: TestComponentBuilder;
/**
* @ngdoc property
* @name component
* @propertyOf spec.ComponentTestHelper
* @description
* The parsed component instance
*/
component: T;
/**
* @ngdoc property
* @name debugElement
* @propertyOf spec.ComponentTestHelper
* @description
* The debugElement representing a JQuery element attached to the component
* on mock page.
*/
debugElement: INgForwardJQuery;
/**
* @ngdoc method
* @name constructor
* @methodOf spec.ComponentTestHelper
* @description
* The constructor for this component.
*/
constructor(mockComponent: ngClass, done: Function) {
this.mockComponent = mockComponent;
this.tcb = new TestComponentBuilder();
this.init(done);
}
/**
* @ngdoc method
* @name init
* @methodOf spec.ComponentTestHelper
* @description
* The initializer function. It is called inside the constructor
*/
init(done: Function): any {
let promisse = this.tcb.createAsync(this.mockComponent) as Promise;
return promisse.then((fixture: any) => {
// Fire all angular events and parsing
fixture.detectChanges();
// The main debug element
this.debugElement = fixture.debugElement;
this.component = this.debugElement.componentViewChildren[0].componentInstance;
let mockObj = new this.mockComponent();
Object.keys(mockObj).forEach((key: any) => {
(this.component)[key] = mockObj[key];
});
}).then(() => {
// Force the resolution of components and sync
done();
});
}
/**
* @ngdoc method
* @name all
* @methodOf spec.ComponentTestHelper
* @description
* Return all elements matching the given selector
*/
all(selector: string): INgForwardJQuery[] {
return this.debugElement.queryAll(selector);
}
/**
* @ngdoc method
* @name find
* @methodOf spec.ComponentTestHelper
* @description
* Return the first element matching the given selector
*/
find(selector: string): INgForwardJQuery {
return this.all(selector)[0];
}
/**
* @ngdoc method
* @name findChildren
* @methodOf spec.ComponentTestHelper
* @description
* Return the first element of parent element that matches the given selector
*/
findChildren(parentSelector: string, childSelector: string) {
let parentComponent = this.find(parentSelector);
return parentComponent.find(childSelector)[0];
}
}
export function createClass({
template = '',
directives = [],
providers = [],
properties = {}
}): any {
@Component({ selector: 'component-test-helper-container', template, directives, providers })
class Test {
constructor() {
Object.keys(properties).forEach((key: any) => {
(this)[key] = properties[key];
});
}
}
return Test;
}