UNPKG

3.66 kBJavaScriptView Raw
1import { View } from 'aurelia-templating';
2import { waitFor } from './wait';
3export class StageComponent {
4 static withResources(resources = []) {
5 return new ComponentTester().withResources(resources);
6 }
7}
8export class ComponentTester {
9 constructor() {
10 this.resources = [];
11 }
12 configure(aurelia) {
13 return aurelia.use.standardConfiguration();
14 }
15 bootstrap(configure) {
16 this.configure = configure;
17 }
18 withResources(resources) {
19 this.resources = resources;
20 return this;
21 }
22 inView(html) {
23 this.html = html;
24 return this;
25 }
26 boundTo(bindingContext) {
27 this.bindingContext = bindingContext;
28 return this;
29 }
30 manuallyHandleLifecycle() {
31 this._prepareLifecycle();
32 return this;
33 }
34 create(bootstrap) {
35 return bootstrap((aurelia) => {
36 return Promise.resolve(this.configure(aurelia)).then(() => {
37 if (this.resources) {
38 aurelia.use.globalResources(this.resources);
39 }
40 return aurelia.start().then(() => {
41 this.host = document.createElement('div');
42 this.host.innerHTML = this.html;
43 document.body.appendChild(this.host);
44 return aurelia.enhance(this.bindingContext, this.host).then(() => {
45 this.rootView = aurelia.root;
46 this.element = this.host.firstElementChild;
47 if (aurelia.root.controllers.length) {
48 this.viewModel = aurelia.root.controllers[0].viewModel;
49 }
50 return new Promise(resolve => setTimeout(() => resolve(), 0));
51 });
52 });
53 });
54 });
55 }
56 dispose() {
57 if (this.host === undefined || this.rootView === undefined) {
58 throw new Error('Cannot call ComponentTester.dispose() before ComponentTester.create()');
59 }
60 this.rootView.detached();
61 this.rootView.unbind();
62 return this.host.parentNode.removeChild(this.host);
63 }
64 _prepareLifecycle() {
65 // bind
66 const bindPrototype = View.prototype.bind;
67 // tslint:disable-next-line:no-empty
68 View.prototype.bind = () => { };
69 this.bind = bindingContext => new Promise(resolve => {
70 View.prototype.bind = bindPrototype;
71 if (bindingContext !== undefined) {
72 this.bindingContext = bindingContext;
73 }
74 this.rootView.bind(this.bindingContext);
75 setTimeout(() => resolve(), 0);
76 });
77 // attached
78 const attachedPrototype = View.prototype.attached;
79 // tslint:disable-next-line:no-empty
80 View.prototype.attached = () => { };
81 this.attached = () => new Promise(resolve => {
82 View.prototype.attached = attachedPrototype;
83 this.rootView.attached();
84 setTimeout(() => resolve(), 0);
85 });
86 // detached
87 this.detached = () => new Promise(resolve => {
88 this.rootView.detached();
89 setTimeout(() => resolve(), 0);
90 });
91 // unbind
92 this.unbind = () => new Promise(resolve => {
93 this.rootView.unbind();
94 setTimeout(() => resolve(), 0);
95 });
96 }
97 waitForElement(selector, options) {
98 return waitFor(() => this.element.querySelector(selector), options);
99 }
100 waitForElements(selector, options) {
101 return waitFor(() => this.element.querySelectorAll(selector), options);
102 }
103}