Skip to content

Commit 65c2e84

Browse files
committed
refactor(artist): rewrite artist whole logic
1 parent e7412aa commit 65c2e84

File tree

24 files changed

+564
-457
lines changed

24 files changed

+564
-457
lines changed
Lines changed: 171 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1-
// tslint:disable: import-name
1+
// tslint:disable-next-line: import-name
22
import Artist from "../src";
33

4+
const delay = (ms: number) => new Promise((r: Function) => setTimeout(r, ms));
45
describe("artist ui", () => {
56
let artist: Artist;
7+
let output: any;
68

79
beforeEach(() => {
810
artist = new Artist();
9-
artist.createStore({});
11+
artist.rewriteScreen = jest.fn().mockImplementation((input) => {
12+
output = input;
13+
});
14+
});
15+
16+
afterAll(() => {
17+
artist.clearAllTimers();
18+
artist = null;
1019
});
1120

1221
it("should load default elements", () => {
@@ -21,120 +30,174 @@ describe("artist ui", () => {
2130
"spinner",
2231
"progress",
2332
"unknown",
24-
"key",
2533
"box",
2634
]);
2735
});
28-
it("should memoize the elements function", () => {
29-
let count = 0;
30-
const dummyElement = () => {
31-
count += 1;
32-
return `dummy-text - ${count}`;
33-
};
34-
artist["registerElements"]({ dummyElement });
35-
const items = Array(2).fill("");
36-
const elemFn = artist["elements"]["dummyElement"];
37-
items.forEach(() => expect(elemFn()).toEqual("dummy-text - 1"));
38-
});
39-
it("should add random ids to elements", () => {
40-
let count = 0;
41-
const tpl = `
42-
<div>
43-
<span>hello</span>
44-
<div name="john"></div>
45-
<row>
46-
<dummy/>
47-
<dummy2 name="peter"/>
48-
</row>
49-
</div>`;
50-
const tplWithIds = `
51-
<div id="div-one">
52-
<span id="span-two">hello</span>
53-
<div name="john" id="div-three"></div>
54-
<row id="row-four">
55-
<dummy id="dummy-five"/>
56-
<dummy2 name="peter" id="dummy2-six"/>
57-
</row>
58-
</div>`;
36+
it("should preserve whitespace", () => {
37+
const tpl = `line1
38+
39+
line2`;
40+
artist.render(() => tpl);
41+
expect(output).toEqual(tpl);
42+
});
43+
it("should remove whitespace", () => {
44+
artist["config"].collapseWhitespace = true;
45+
const tpl = `line1
46+
47+
line2`;
48+
const expected = `line1 line2`;
49+
artist.render(() => tpl);
50+
expect(output).toEqual(expected);
51+
});
52+
it("should preserve line breaks", () => {
53+
artist["config"].preserveLineBreaks = true;
54+
const tpl = `line1
5955
60-
const idGenerator = () => {
61-
const ids = ["one", "two", "three", "four", "five", "six"];
62-
const id = ids[count];
63-
count += 1;
64-
return id;
56+
line2`;
57+
artist.render(() => tpl);
58+
expect(output).toEqual(tpl);
59+
});
60+
it("should register new elements", () => {
61+
const tagEl = {
62+
name: "tag",
63+
render: () => `I am tag!`,
64+
};
65+
artist.registerEls({ tagEl });
66+
artist.render(() => `<tag></tag>`);
67+
expect(output).toEqual("I am tag!");
68+
});
69+
it("should run init hook for elements", () => {
70+
const tagEl = {
71+
name: "tag",
72+
init: ({ store }) => {
73+
if (!store.tags) store.tags = ["one", "two"];
74+
},
75+
render: ({ store }) => `I am tag!- ${store.tags}`,
6576
};
66-
const templateStr = artist.addElementID(tpl, idGenerator);
67-
expect(templateStr).toEqual(tplWithIds);
68-
});
69-
it("should not add id if it already exists", () => {
70-
let count = 0;
71-
const tpl = `
72-
<div id="one">
73-
<span id="two">hello</span>
74-
<div name="john"></div>
75-
<row>
76-
<dummy/>
77-
<dummy2 name="peter"/>
78-
</row>
79-
</div>`;
80-
const tplWithIds = `
81-
<div id="one">
82-
<span id="two">hello</span>
83-
<div name="john" id="div-three"></div>
84-
<row id="row-four">
85-
<dummy id="dummy-five"/>
86-
<dummy2 name="peter" id="dummy2-six"/>
87-
</row>
88-
</div>`;
77+
artist.registerEls({ tagEl });
78+
artist.render(() => `<tag></tag>`);
79+
expect(output).toEqual("I am tag!- one,two");
80+
});
81+
it("should convert element data to object", () => {
82+
const tagEl = {
83+
name: "tag",
84+
init: ({ store }) => {
85+
if (!store.tags) store.tags = ["one", "two"];
86+
},
87+
render: (_: any, data: any) => JSON.stringify(data),
88+
};
89+
artist.registerEls({ tagEl });
90+
artist.render(() => `<tag name="hi">one</tag>`);
91+
expect(output).toEqual(
92+
JSON.stringify({
93+
type: "element",
94+
tagName: "tag",
95+
attributes: [{ key: "name", value: "hi" }],
96+
children: [{ type: "text", content: "one" }],
97+
}),
98+
);
99+
});
100+
it("should get element props", () => {
101+
const tagEl = {
102+
name: "tag",
103+
render: (ctx: any) => `props: ${Object.entries(ctx.props)}`,
104+
};
105+
artist.registerEls({ tagEl });
106+
artist.render(() => `<tag name="doe" age="21" bool="false">one</tag>`);
107+
expect(output).toEqual("props: name,doe,age,21,bool,false");
108+
});
109+
it("should recursively load elements", () => {
110+
const tagEl = {
111+
name: "tag",
112+
render: () => `<text>hello</text>`,
113+
};
114+
artist.registerEls({ tagEl });
115+
artist.render(() => `@<div><tag></tag> ##</div>@`);
116+
expect(output).toEqual(`@
117+
hello ##
118+
@`);
119+
});
120+
it("should run global init", () => {
121+
artist.onInit((store: any) => {
122+
if (store.count === undefined) store.count = 0;
123+
});
124+
artist.render((store: any) => `<text>counter ${store.count}</text>`);
125+
expect(output).toEqual("counter 0");
126+
});
127+
it("should run global init timer", async () => {
128+
artist.onInit((store: any, timer: Function) => {
129+
if (store.count === undefined) store.count = 0;
130+
timer(() => {
131+
store.count += 1;
132+
}, 500);
133+
});
89134

90-
const idGenerator = () => {
91-
const ids = ["three", "four", "five", "six"];
92-
const id = ids[count];
93-
count += 1;
94-
return id;
135+
artist.render((store: any) => `<text>counter ${store.count}</text>`);
136+
await delay(1000);
137+
expect(output).toEqual("counter 1");
138+
artist.clearAllTimers();
139+
});
140+
it("should run internal timer", async () => {
141+
const tagEl = {
142+
name: "tag",
143+
init: ({ store, timer }) => {
144+
if (store.num === undefined) store.num = 0;
145+
timer(
146+
() => {
147+
store.num += 1;
148+
},
149+
100,
150+
"someid",
151+
);
152+
},
153+
render: ({ store }) => `I am tag!- ${store.num}`,
95154
};
96-
const templateStr = artist.addElementID(tpl, idGenerator);
97-
expect(templateStr).toEqual(tplWithIds);
155+
artist.registerEls({ tagEl });
156+
artist.render(() => `<tag></tag>`);
157+
await delay(200);
158+
artist.clearAllTimers();
159+
expect(output).toEqual("I am tag!- 1");
160+
});
161+
it("should clear all unsued timers", () => {
162+
jest.useFakeTimers();
163+
artist.onInit(async (store: any) => {
164+
store.dotsSpinner = true;
165+
store.arcSpinner = false;
166+
await delay(200);
167+
store.dotsSpinner = true;
168+
store.arcSpinner = false;
169+
});
170+
artist.render(
171+
(store: any) =>
172+
`${store.dotsSpinner ? `<spinner type="dots"/>` : ""}${
173+
store.arcSpinner ? `<spinner type="arc"/>` : ""
174+
}`,
175+
);
176+
expect(artist["runningElTimers"]).toEqual(["dots"]);
177+
artist.clearAllTimers();
178+
jest.useRealTimers();
98179
});
99-
it("should get element store", () => {
100-
artist.createStore({
101-
month: { name: "march" },
180+
xit("should dispose all timers", () => {
181+
jest.useFakeTimers();
182+
artist.onInit((store: any, timer: Function) => {
183+
if (store.count === undefined) store.count = 0;
184+
timer(() => (store.count += 1), 100, "count");
102185
});
103-
expect(
104-
artist.getElementStore({ attributes: [{ key: "id", value: "month" }] }),
105-
).toEqual({ name: "march" });
106-
});
107-
it("should minify the template", () => {
108-
const tpl = `<div id="one">
109-
<span id="two">hello</span>
110-
<div name="john"> content </div>
111-
<div></div>
112-
</div>`;
113-
const minifiedTpl =
114-
'<div id="one"><span id="two">hello</span><div name="john">content</div><div></div></div>';
115-
expect(artist.minifyTpl(tpl)).toEqual(minifiedTpl);
116-
});
117-
it("should compile the template", () => {
118-
const tpl = `<div id="one">
119-
<span id="two">{{name}}</span>
120-
<div name="john"> {{content}} </div>
121-
<div></div>`;
122-
artist.createStore({
123-
name: "vylson",
124-
content: "hello",
186+
artist.render(() => `1<spinner/>`);
187+
expect(artist["timers"]).toEqual({
188+
global: { count: true },
189+
internal: { dots: true },
125190
});
126-
const expected = `<div id="one">
127-
<span id="two">vylson</span>
128-
<div name="john"> hello </div>
129-
<div></div>`;
130-
expect(artist.compileTpl(tpl)).toEqual(expected);
131-
});
132-
it.skip("should pass only sliced store to element", () => {});
133-
it.skip("should update display text on store change", () => {});
134-
it.skip("should dispose all timers", () => {});
135-
it.skip("should recursively load elements", () => {});
136-
it.skip("should update the template with store data", () => {});
137-
it.skip("should parse the templates to object", () => {});
138-
it.skip("should register new elements", () => {});
139-
it.skip("should get changed store elements", () => {});
191+
artist.clearAllTimers();
192+
expect(artist["timers"]).toEqual({ global: {}, internal: {} });
193+
jest.useRealTimers();
194+
});
195+
196+
xit("should update display text on store change", async () => {
197+
artist.render((store: any) => `name - ${store.name}`);
198+
expect(output).toEqual("name - undefined");
199+
artist["store"].name = "foobar";
200+
await delay(10);
201+
expect(output).toEqual("name - foobar");
202+
});
140203
});

0 commit comments

Comments
 (0)