1 | import xs, {Stream, MemoryStream} from 'xstream';
|
2 | import {DevToolEnabledSource, FantasyObservable} from '@cycle/run';
|
3 | import {VNode} from 'snabbdom';
|
4 | import {DOMSource, EventsFnOptions} from './DOMSource';
|
5 | import {adapt} from '@cycle/run/lib/adapt';
|
6 |
|
7 | export type MockConfig = {
|
8 | [name: string]: FantasyObservable<any> | MockConfig;
|
9 | };
|
10 |
|
11 | const SCOPE_PREFIX = '___';
|
12 |
|
13 | export class MockedDOMSource {
|
14 | private _elements: FantasyObservable<any>;
|
15 |
|
16 | constructor(private _mockConfig: MockConfig) {
|
17 | if (_mockConfig.elements) {
|
18 | this._elements = _mockConfig.elements as FantasyObservable<any>;
|
19 | } else {
|
20 | this._elements = adapt(xs.empty());
|
21 | }
|
22 | }
|
23 |
|
24 | public elements(): any {
|
25 | const out: Partial<DevToolEnabledSource> & FantasyObservable<any> = this
|
26 | ._elements;
|
27 | out._isCycleSource = 'MockedDOM';
|
28 | return out;
|
29 | }
|
30 |
|
31 | public element(): any {
|
32 | const output$: MemoryStream<Element> = this.elements()
|
33 | .filter((arr: Array<any>) => arr.length > 0)
|
34 | .map((arr: Array<any>) => arr[0])
|
35 | .remember();
|
36 | const out: DevToolEnabledSource & MemoryStream<Element> = adapt(output$);
|
37 | out._isCycleSource = 'MockedDOM';
|
38 | return out;
|
39 | }
|
40 |
|
41 | public events(
|
42 | eventType: string,
|
43 | options?: EventsFnOptions,
|
44 | bubbles?: boolean
|
45 | ): any {
|
46 | const streamForEventType = this._mockConfig[eventType] as any;
|
47 | const out: DevToolEnabledSource & FantasyObservable<any> = adapt(
|
48 | streamForEventType || xs.empty()
|
49 | );
|
50 |
|
51 | out._isCycleSource = 'MockedDOM';
|
52 |
|
53 | return out;
|
54 | }
|
55 |
|
56 | public select(selector: string): MockedDOMSource {
|
57 | const mockConfigForSelector = this._mockConfig[selector] || {};
|
58 |
|
59 | return new MockedDOMSource(mockConfigForSelector as MockConfig);
|
60 | }
|
61 |
|
62 | public isolateSource(
|
63 | source: MockedDOMSource,
|
64 | scope: string
|
65 | ): MockedDOMSource {
|
66 | return source.select('.' + SCOPE_PREFIX + scope);
|
67 | }
|
68 |
|
69 | public isolateSink(sink: any, scope: string): any {
|
70 | return adapt(
|
71 | xs.fromObservable<any>(sink).map((vnode: VNode) => {
|
72 | if (vnode.sel && vnode.sel.indexOf(SCOPE_PREFIX + scope) !== -1) {
|
73 | return vnode;
|
74 | } else {
|
75 | vnode.sel += `.${SCOPE_PREFIX}${scope}`;
|
76 | return vnode;
|
77 | }
|
78 | })
|
79 | );
|
80 | }
|
81 | }
|
82 |
|
83 | export function mockDOMSource(mockConfig: MockConfig): MockedDOMSource {
|
84 | return new MockedDOMSource(mockConfig);
|
85 | }
|
86 |
|
\ | No newline at end of file |