Skip to content

Commit 0d30a1b

Browse files
committed
[add] Test scripts
1 parent 6d9291b commit 0d30a1b

File tree

8 files changed

+126
-10
lines changed

8 files changed

+126
-10
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
package-lock.json
2-
node_modules/
2+
node_modules/
3+
.vscode/

package.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@
2121
},
2222
"source": "source/index.ts",
2323
"devDependencies": {
24+
"@types/core-js": "^2.5.3",
2425
"@types/jest": "^25.1.4",
2526
"@types/jsdom": "^16.1.0",
27+
"core-js": "^3.6.4",
28+
"husky": "^4.2.3",
2629
"jest": "^25.1.0",
2730
"jsdom": "^16.2.1",
2831
"lint-staged": "^10.0.8",
@@ -41,9 +44,17 @@
4144
},
4245
"jest": {
4346
"preset": "ts-jest",
44-
"testEnvironment": "node"
47+
"testEnvironment": "node",
48+
"globals": {
49+
"ts-jest": {
50+
"tsConfig": "test/tsconfig.json"
51+
}
52+
}
4553
},
4654
"scripts": {
4755
"test": "lint-staged && jest"
56+
},
57+
"husky": {
58+
"pre-commit": "npm test"
4859
}
4960
}

source/factory.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
import { CustomElementClass, VChild, VNode } from './type';
22

3+
const custom_cache = new WeakMap();
4+
35
export function createCell(
46
tag: string | Function | CustomElementClass,
57
data?: any,
6-
...childNodes: VChild[]
8+
...children: VChild[]
79
): VNode {
10+
children = children.flat(Infinity);
11+
812
if (typeof tag === 'function') {
9-
try {
10-
const node = new (tag as CustomElementClass)();
13+
let name = custom_cache.get(tag);
14+
15+
if (name) tag = name;
16+
else
17+
try {
18+
const node = new (tag as CustomElementClass)();
19+
20+
if (node instanceof HTMLElement) {
21+
name = node.tagName.toLowerCase();
1122

12-
if (node instanceof HTMLElement) tag = node.tagName.toLowerCase();
13-
} catch {}
23+
custom_cache.set(tag, (tag = name));
24+
}
25+
} catch {}
1426

15-
if (typeof tag === 'function') return (tag as Function)(data);
27+
if (typeof tag === 'function')
28+
return (tag as Function)({ ...data, children });
1629
}
1730

18-
return { ...data, tagName: tag, childNodes };
31+
return { ...data, tagName: tag, childNodes: children };
1932
}

source/global.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
declare namespace JSX {
2+
interface ElementChildrenAttribute {
3+
children: any;
4+
}
5+
}

test/factory.spec.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import './polyfill';
2+
import { createCell } from '../source';
3+
4+
describe('JSX Factory method', () => {
5+
it('should accept a Standard HTML Tag', () => {
6+
expect(<a>test</a>).toEqual(
7+
expect.objectContaining({
8+
tagName: 'a',
9+
childNodes: ['test']
10+
})
11+
);
12+
});
13+
14+
it('should accept a Function Component', () => {
15+
const Test = ({ children }) => <a>{children}</a>;
16+
17+
expect(<Test>test</Test>).toEqual(
18+
expect.objectContaining({
19+
tagName: 'a',
20+
childNodes: ['test']
21+
})
22+
);
23+
});
24+
25+
it('should accept a Class Component', () => {
26+
class Test extends HTMLElement {}
27+
28+
customElements.define('x-test', Test);
29+
30+
expect(<Test />).toEqual(
31+
expect.objectContaining({
32+
tagName: 'x-test',
33+
childNodes: []
34+
})
35+
);
36+
});
37+
});

test/polyfill.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import 'core-js/es/array/flat';
12
import { JSDOM } from 'jsdom';
23

34
const { window } = new JSDOM();
45

5-
for (const key of ['window', 'document', 'customElements'])
6+
for (const key of ['window', 'document', 'HTMLElement', 'customElements'])
67
global[key] = window[key];

test/renderer.spec.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import './polyfill';
2+
import { update, createCell } from '../source';
3+
4+
describe('Renderer methods', () => {
5+
document.body.innerHTML = '<a title="test" />';
6+
7+
it('should update a Standard HTML Tag', () => {
8+
update(document.body.firstElementChild, <a href="#">test</a>);
9+
10+
expect(document.body.innerHTML).toBe('<a href="#">test</a>');
11+
});
12+
13+
it('should relpace an old HTML Tag', () => {
14+
update(
15+
document.body.firstElementChild,
16+
<ol>
17+
<li id="item-1">1</li>
18+
<li id="item-0">0</li>
19+
</ol>
20+
);
21+
22+
expect(document.body.innerHTML).toBe(
23+
'<ol><li id="item-1">1</li><li id="item-0">0</li></ol>'
24+
);
25+
});
26+
27+
it('should relpace an old HTML Tag', () => {
28+
const root = document.body.firstElementChild;
29+
const last = root.lastElementChild;
30+
31+
update(
32+
document.body.firstElementChild,
33+
<ol>
34+
<li id="item-0">0</li>
35+
</ol>
36+
);
37+
38+
expect(root.outerHTML).toBe('<ol><li id="item-0">0</li></ol>');
39+
expect(root.lastElementChild).toBe(last);
40+
});
41+
});

test/tsconfig.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"compilerOptions": {
4+
"target": "ES6"
5+
},
6+
"include": ["../source/*.ts", "*.ts", "*.tsx"]
7+
}

0 commit comments

Comments
 (0)