190 lines
6.6 KiB
TypeScript
190 lines
6.6 KiB
TypeScript
import { describe, expect, it, afterAll, beforeAll } from 'vitest';
|
|
import { config, parse, parseCode, parseView } from './mock';
|
|
import { types as t } from '@babel/core';
|
|
import type { CompUnit, HTMLUnit } from '../index';
|
|
|
|
describe('ElementUnit', () => {
|
|
beforeAll(() => {
|
|
// ---- Ignore template for this test
|
|
config.parseTemplate = false;
|
|
});
|
|
|
|
afterAll(() => {
|
|
config.parseTemplate = true;
|
|
});
|
|
|
|
// ---- Type
|
|
it('should identify a JSX element with tag in htmlTags as an HTMLUnit', () => {
|
|
const viewUnits = parse('<div></div>');
|
|
expect(viewUnits.length).toBe(1);
|
|
expect(viewUnits[0].type).toBe('html');
|
|
});
|
|
|
|
it('should identify a JSX element with tag not in htmlTags as an CompUnit', () => {
|
|
const viewUnits = parse('<Comp></Comp>');
|
|
expect(viewUnits.length).toBe(1);
|
|
expect(viewUnits[0].type).toBe('comp');
|
|
});
|
|
|
|
it('should identify a JSX element with namespaced "html" outside htmlTags as an HTMLUnit', () => {
|
|
const viewUnits = parse('<html:MyWebComponent></html:MyWebComponent>');
|
|
expect(viewUnits.length).toBe(1);
|
|
expect(viewUnits[0].type).toBe('html');
|
|
});
|
|
|
|
it('should identify a JSX element with namespaced "tag" outside htmlTags as an HTMLUnit', () => {
|
|
const viewUnits = parse('<tag:variable></tag:variable>');
|
|
expect(viewUnits.length).toBe(1);
|
|
expect(viewUnits[0].type).toBe('html');
|
|
});
|
|
|
|
it('should identify a JSX element with namespaced "comp" inside htmlTags as an HTMLUnit', () => {
|
|
const viewUnits = parse('<comp:div></comp:div>');
|
|
expect(viewUnits.length).toBe(1);
|
|
expect(viewUnits[0].type).toBe('comp');
|
|
});
|
|
|
|
it('should identify a JSX element with name equal to "env" as an EnvUnit', () => {
|
|
const viewUnits = parse('<env></env>');
|
|
expect(viewUnits.length).toBe(1);
|
|
expect(viewUnits[0].type).toBe('env');
|
|
});
|
|
|
|
// ---- Tag
|
|
it('should correctly parse the tag of an HTMLUnit', () => {
|
|
const viewUnits = parse('<div></div>');
|
|
const tag = (viewUnits[0] as HTMLUnit).tag;
|
|
|
|
expect(t.isStringLiteral(tag, { value: 'div' })).toBeTruthy();
|
|
});
|
|
|
|
it('should correctly parse the tag of an HTMLUnit with namespaced "html"', () => {
|
|
const viewUnits = parse('<html:MyWebComponent></html:MyWebComponent>');
|
|
const tag = (viewUnits[0] as HTMLUnit).tag;
|
|
|
|
expect(t.isStringLiteral(tag, { value: 'MyWebComponent' })).toBeTruthy();
|
|
});
|
|
|
|
it('should correctly parse the tag of an HTMLUnit with namespaced "tag"', () => {
|
|
const viewUnits = parse('<tag:variable></tag:variable>');
|
|
const tag = (viewUnits[0] as HTMLUnit).tag;
|
|
|
|
expect(t.isIdentifier(tag, { name: 'variable' })).toBeTruthy();
|
|
});
|
|
|
|
it('should correctly parse the tag of an CompUnit', () => {
|
|
const viewUnits = parse('<Comp></Comp>');
|
|
const tag = (viewUnits[0] as HTMLUnit).tag;
|
|
|
|
expect(t.isIdentifier(tag, { name: 'Comp' })).toBeTruthy();
|
|
});
|
|
|
|
it('should correctly parse the tag of an CompUnit with namespaced "comp"', () => {
|
|
const viewUnits = parse('<comp:div></comp:div>');
|
|
const tag = (viewUnits[0] as HTMLUnit).tag;
|
|
|
|
expect(t.isIdentifier(tag, { name: 'div' })).toBeTruthy();
|
|
});
|
|
|
|
// ---- Props(for both HTMLUnit and CompUnit)
|
|
it('should correctly parse the props', () => {
|
|
const viewUnits = parse('<div id="myId"></div>');
|
|
|
|
const htmlUnit = viewUnits[0] as HTMLUnit;
|
|
const props = htmlUnit.props!;
|
|
expect(t.isStringLiteral(props.id.value, { value: 'myId' })).toBeTruthy();
|
|
});
|
|
|
|
it('should correctly parse the props with a complex expression', () => {
|
|
const ast = parseCode('<div onClick={() => {console.log("ok")}}></div>');
|
|
const viewUnits = parseView(ast);
|
|
|
|
const originalExpression = (
|
|
((ast as t.JSXElement).openingElement.attributes[0] as t.JSXAttribute).value as t.JSXExpressionContainer
|
|
).expression;
|
|
|
|
const htmlUnit = viewUnits[0] as HTMLUnit;
|
|
expect(htmlUnit.props!.onClick.value).toBe(originalExpression);
|
|
});
|
|
|
|
it('should correctly parse multiple props', () => {
|
|
const viewUnits = parse('<div id="myId" class="myClass"></div>');
|
|
|
|
const htmlUnit = viewUnits[0] as HTMLUnit;
|
|
const props = htmlUnit.props!;
|
|
expect(Object.keys(props).length).toBe(2);
|
|
expect(t.isStringLiteral(props.id.value, { value: 'myId' })).toBeTruthy();
|
|
expect(t.isStringLiteral(props.class.value, { value: 'myClass' })).toBeTruthy();
|
|
});
|
|
|
|
it('should correctly parse props with namespace as its specifier', () => {
|
|
const viewUnits = parse('<div bind:id="myId"></div>');
|
|
const htmlUnit = viewUnits[0] as HTMLUnit;
|
|
const props = htmlUnit.props!;
|
|
expect(props.id.specifier).toBe('bind');
|
|
expect(t.isStringLiteral(props.id.value, { value: 'myId' })).toBeTruthy();
|
|
});
|
|
|
|
it('should correctly parse spread props', () => {
|
|
const viewUnits = parse('<Comp {...props}></Comp>');
|
|
const htmlUnit = viewUnits[0] as CompUnit;
|
|
const props = htmlUnit.props!;
|
|
expect(t.isIdentifier(props['*spread*'].value, { name: 'props' })).toBeTruthy();
|
|
});
|
|
|
|
// ---- View prop (other test cases can be found in ExpUnit.test.ts)
|
|
it('should correctly parse sub jsx attribute as view prop', () => {
|
|
const ast = parseCode('<Comp sub=<div>Ok</div>></Comp>');
|
|
const viewUnits = parseView(ast);
|
|
|
|
const props = (viewUnits[0] as CompUnit).props!;
|
|
const viewPropMap = props.sub.viewPropMap!;
|
|
expect(Object.keys(viewPropMap).length).toBe(1);
|
|
|
|
const key = Object.keys(viewPropMap)[0];
|
|
const viewProp = viewPropMap[key];
|
|
expect(viewProp.length).toBe(1);
|
|
expect(viewProp[0].type).toBe('html');
|
|
|
|
// ---- Prop View will be replaced with a random string and stored in props.viewPropMap
|
|
const value = props.sub.value;
|
|
expect(t.isStringLiteral(value, { value: key })).toBeTruthy();
|
|
});
|
|
|
|
// ---- Children(for both HTMLUnit and CompUnit)
|
|
it('should correctly parse the count of children', () => {
|
|
const viewUnits = parse(`<div>
|
|
<div>ok</div>
|
|
<div>ok</div>
|
|
<Comp></Comp>
|
|
<Comp></Comp>
|
|
</div>`);
|
|
const htmlUnit = viewUnits[0] as HTMLUnit;
|
|
expect(htmlUnit.children!.length).toBe(4);
|
|
});
|
|
|
|
it('should correctly parse the count of children with JSXExpressionContainer', () => {
|
|
const viewUnits = parse(`<div>
|
|
<div>ok</div>
|
|
<div>ok</div>
|
|
{count}
|
|
{count}
|
|
</div>`);
|
|
const htmlUnit = viewUnits[0] as HTMLUnit;
|
|
expect(htmlUnit.children!.length).toBe(4);
|
|
});
|
|
|
|
it('should correctly parse the count of children with JSXFragment', () => {
|
|
const viewUnits = parse(`<div>
|
|
<div>ok</div>
|
|
<div>ok</div>
|
|
<>
|
|
<Comp></Comp>
|
|
<Comp></Comp>
|
|
</>
|
|
</div>`);
|
|
const htmlUnit = viewUnits[0] as HTMLUnit;
|
|
expect(htmlUnit.children!.length).toBe(4);
|
|
});
|
|
});
|