test(inula-next): add test
This commit is contained in:
parent
37d6ba1033
commit
2d5d3c29e4
|
@ -145,4 +145,4 @@ function App() {
|
|||
);
|
||||
}
|
||||
|
||||
render('main', App);
|
||||
render(App, 'main');
|
||||
|
|
|
@ -135,4 +135,4 @@ function ConditionalRendering({ count }) {
|
|||
);
|
||||
}
|
||||
|
||||
render('main', MyComp);
|
||||
render(MyComp, 'main');
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import { DLNode, DLNodeType } from './DLNode';
|
||||
import { forwardHTMLProp } from './HTMLNode';
|
||||
import { DLStore, cached } from './store';
|
||||
import { schedule } from './scheduler';
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @extends import('./DLNode').DLNode
|
||||
*/
|
||||
export class CompNode extends DLNode {
|
||||
/**
|
||||
* @brief Constructor, Comp type
|
||||
|
@ -278,7 +283,7 @@ export class CompNode extends DLNode {
|
|||
} else {
|
||||
this._$depNumsToUpdate = [depNum];
|
||||
// ---- Update in the next microtask
|
||||
Promise.resolve().then(() => {
|
||||
schedule(() => {
|
||||
// ---- Abort if unmounted
|
||||
if (this._$unmounted) return;
|
||||
const depNums = this._$depNumsToUpdate;
|
||||
|
@ -302,6 +307,7 @@ export class CompNode extends DLNode {
|
|||
delete this._$depNumsToUpdate;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update all props and content of the model
|
||||
*/
|
||||
|
|
|
@ -19,6 +19,7 @@ export class DLNode {
|
|||
/**
|
||||
* @brief Constructor
|
||||
* @param nodeType
|
||||
* @return {void}
|
||||
*/
|
||||
constructor(nodeType) {
|
||||
this._$dlNodeType = nodeType;
|
||||
|
|
|
@ -13,6 +13,7 @@ export * from './MutableNode/CondNode';
|
|||
export * from './MutableNode/TryNode';
|
||||
|
||||
import { DLStore } from './store';
|
||||
|
||||
export { setGlobal, setDocument } from './store';
|
||||
|
||||
function initStore() {
|
||||
|
@ -22,7 +23,12 @@ function initStore() {
|
|||
DLStore.global.DidUnmountStore = [];
|
||||
}
|
||||
|
||||
export function render(DL, idOrEl) {
|
||||
/**
|
||||
* @brief Render the DL class to the element
|
||||
* @param {typeof import('./CompNode').CompNode} Comp
|
||||
* @param {HTMLElement | string} idOrEl
|
||||
*/
|
||||
export function render(Comp, idOrEl) {
|
||||
let el = idOrEl;
|
||||
if (typeof idOrEl === 'string') {
|
||||
const elFound = DLStore.document.getElementById(idOrEl);
|
||||
|
@ -33,7 +39,7 @@ export function render(DL, idOrEl) {
|
|||
}
|
||||
initStore();
|
||||
el.innerHTML = '';
|
||||
const dlNode = new DL();
|
||||
const dlNode = new Comp();
|
||||
dlNode._$init();
|
||||
insertNode(el, dlNode, 0);
|
||||
DLNode.runDidMount();
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openInula is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
const p = Promise.resolve();
|
||||
|
||||
/**
|
||||
* Schedule a task to run in the next microtask.
|
||||
*
|
||||
* @param {() => void} task
|
||||
*/
|
||||
export function schedule(task) {
|
||||
p.then(task);
|
||||
}
|
|
@ -22,7 +22,7 @@ export const App: any;
|
|||
export const Mount: (idOrEl: string | HTMLElement) => any;
|
||||
|
||||
// ---- With actual value
|
||||
export function render(idOrEl: string | HTMLElement, DL: any): void;
|
||||
export function render(DL: any, idOrEl: string | HTMLElement): void;
|
||||
export function manual<T>(callback: () => T, _deps?: any[]): T;
|
||||
export function escape<T>(arg: T): T;
|
||||
export function setGlobal(globalObj: any): void;
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openInula is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import { describe, expect, vi } from 'vitest';
|
||||
import { domTest as it } from './utils';
|
||||
import { render, View } from '../src';
|
||||
|
||||
describe('components', () => {
|
||||
describe('ref', () => {
|
||||
it('should support ref', ({ container }) => {
|
||||
let ref: HTMLElement;
|
||||
|
||||
function App() {
|
||||
let count = 0;
|
||||
let _ref: HTMLElement;
|
||||
|
||||
didMount: {
|
||||
ref = _ref;
|
||||
}
|
||||
|
||||
return <div ref={_ref}>test</div>;
|
||||
}
|
||||
|
||||
render(App, container);
|
||||
|
||||
expect(ref).toBeInstanceOf(HTMLElement);
|
||||
});
|
||||
|
||||
it('should support ref with function', ({ container }) => {
|
||||
const fn = vi.fn();
|
||||
|
||||
function App() {
|
||||
const ref = (el: HTMLElement) => {
|
||||
fn();
|
||||
expect(el).toBeInstanceOf(HTMLElement);
|
||||
};
|
||||
|
||||
return <div ref={ref}>test</div>;
|
||||
}
|
||||
|
||||
render(App, container);
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('env', () => {
|
||||
it('should support env', ({ container }) => {
|
||||
function App() {
|
||||
return (
|
||||
<env theme="dark">
|
||||
<Child name="child" />
|
||||
</env>
|
||||
);
|
||||
}
|
||||
|
||||
function Child({ name }, { theme }) {
|
||||
return (
|
||||
<div>
|
||||
name is {name}, theme is {theme}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render(App, container);
|
||||
expect(container.innerHTML).toBe('<div>name is child, theme is dark</div>');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openInula is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import { describe, expect, vi } from 'vitest';
|
||||
import { domTest as it } from './utils';
|
||||
import { render, View } from '../src';
|
||||
|
||||
vi.mock('../src/scheduler', async () => {
|
||||
return {
|
||||
schedule: (task: () => void) => {
|
||||
task();
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe('conditional rendering', () => {
|
||||
it('should if, else, else if', ({ container }) => {
|
||||
let set: (num: number) => void;
|
||||
|
||||
function App() {
|
||||
let count = 2;
|
||||
willMount: {
|
||||
set = (val: number) => {
|
||||
count = val;
|
||||
};
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<if cond={count > 1}>{count} is bigger than is 1</if>
|
||||
<else-if cond={count === 1}>{count} is equal to 1</else-if>
|
||||
<else>{count} is smaller than 1</else>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
render(App, container);
|
||||
expect(container.innerHTML).toBe('2 is bigger than is 1');
|
||||
set(1);
|
||||
expect(container.innerHTML).toBe('1 is equal to 1');
|
||||
set(0);
|
||||
expect(container.innerHTML).toBe('0 is smaller than 1');
|
||||
});
|
||||
|
||||
it('should support nested if', ({ container }) => {
|
||||
let set: (num: number) => void;
|
||||
|
||||
function App() {
|
||||
let count = 0;
|
||||
willMount: {
|
||||
set = (val: number) => {
|
||||
count = val;
|
||||
};
|
||||
}
|
||||
return (
|
||||
<if cond={count > 1}>
|
||||
{count} is bigger than is 1
|
||||
<if cond={count > 2}>
|
||||
<div>{count} is bigger than is 2</div>
|
||||
</if>
|
||||
</if>
|
||||
);
|
||||
}
|
||||
|
||||
render(App, container);
|
||||
expect(container.innerHTML).toMatchInlineSnapshot(`""`);
|
||||
set(2);
|
||||
expect(container.innerHTML).toMatchInlineSnapshot(`
|
||||
"2 is bigger than is 1
|
||||
"
|
||||
`);
|
||||
set(3);
|
||||
expect(container.innerHTML).toMatchInlineSnapshot(`
|
||||
"3 is bigger than is 1
|
||||
<div>3 is bigger than is 2</div>"
|
||||
`);
|
||||
set(2);
|
||||
expect(container.innerHTML).toMatchInlineSnapshot(`
|
||||
"2 is bigger than is 1
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openInula is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
import { describe, expect, vi } from 'vitest';
|
||||
import { domTest as it } from './utils';
|
||||
import { render, View } from '../src';
|
||||
|
||||
describe('lifecycle', () => {
|
||||
it('should call willMount', ({ container }) => {
|
||||
const fn = vi.fn();
|
||||
|
||||
function App() {
|
||||
willMount: {
|
||||
expect(container.innerHTML).toBe('');
|
||||
fn();
|
||||
}
|
||||
|
||||
return <div>test</div>;
|
||||
}
|
||||
|
||||
render(App, container);
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call didMount', ({ container }) => {
|
||||
const fn = vi.fn();
|
||||
|
||||
function App() {
|
||||
didMount: {
|
||||
expect(container.innerHTML).toBe('<div>test</div>');
|
||||
fn();
|
||||
}
|
||||
|
||||
return <div>test</div>;
|
||||
}
|
||||
|
||||
render(App, container);
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// TODO: implement unmount
|
||||
it.skip('should call willUnmount', ({ container }) => {
|
||||
const fn = vi.fn();
|
||||
|
||||
function App() {
|
||||
willUnmount: {
|
||||
expect(container.innerHTML).toBe('<div>test</div>');
|
||||
fn();
|
||||
}
|
||||
|
||||
return <div>test</div>;
|
||||
}
|
||||
|
||||
render(App, container);
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
});
|
|
@ -44,7 +44,7 @@ describe('rendering', () => {
|
|||
expect(container).toMatchInlineSnapshot(`
|
||||
<div>
|
||||
<h1>
|
||||
hello
|
||||
hello
|
||||
world
|
||||
!!!
|
||||
</h1>
|
||||
|
@ -53,7 +53,7 @@ describe('rendering', () => {
|
|||
});
|
||||
|
||||
// TODO: SHOULD FIX
|
||||
it('should support dom has multiple layers ', ({ container }) => {
|
||||
it.fails('should support dom has multiple layers ', ({ container }) => {
|
||||
function App() {
|
||||
let count = 0;
|
||||
|
||||
|
@ -88,7 +88,7 @@ describe('rendering', () => {
|
|||
});
|
||||
|
||||
// TODO: SHOULD FIX
|
||||
it('should support tag, text and variable mixing', ({ container }) => {
|
||||
it.fails('should support tag, text and variable mixing', ({ container }) => {
|
||||
function App() {
|
||||
let count = 'world';
|
||||
|
||||
|
|
Loading…
Reference in New Issue