diff --git a/packages/devui-vue/devui-cli/commands/code-check.js b/packages/devui-vue/devui-cli/commands/code-check.js index f3e6b78290..de6f4e35b0 100644 --- a/packages/devui-vue/devui-cli/commands/code-check.js +++ b/packages/devui-vue/devui-cli/commands/code-check.js @@ -50,7 +50,7 @@ const eslintCheck = async (components) => { const unitTestSingle = async (name) => { log(chalkUnitTest(`Start unit test ${name}...`)); - await shell.exec(`pnpm test --filter vue-devui -- --colors --noStackTrace --testMatch **/${name}.spec.ts`); + await shell.exec(`pnpm test --filter vue-devui -- --colors --noStackTrace --testMatch **/${name}/**/{*.spec.ts,*.spec.tsx}`); log(chalkUnitTest(`Unit test ${name} finished!`)); }; diff --git a/packages/devui-vue/devui/tree/__tests__/basic-tree/basic-data.ts b/packages/devui-vue/devui/tree/__tests__/basic-tree/basic-data.ts new file mode 100644 index 0000000000..a60e975bd4 --- /dev/null +++ b/packages/devui-vue/devui/tree/__tests__/basic-tree/basic-data.ts @@ -0,0 +1,29 @@ +import { ref } from 'vue'; + +export const basicData = ref([ + { + label: 'Parent node 1', + open: true, + disabled: true, + children: [ + { + label: 'Parent node 1-1', + disableToggle: true, + children: [ + { + label: 'Leaf node 1-1-1', + } + ] + }, + { + label: 'Leaf node 1-2', + }, + { + label: 'Leaf node 1-3', + }, + ] + }, + { + label: 'Leaf node 2', + } +]); diff --git a/packages/devui-vue/devui/tree/__tests__/basic-tree/basic-tree.spec.tsx b/packages/devui-vue/devui/tree/__tests__/basic-tree/basic-tree.spec.tsx new file mode 100644 index 0000000000..efb35cf726 --- /dev/null +++ b/packages/devui-vue/devui/tree/__tests__/basic-tree/basic-tree.spec.tsx @@ -0,0 +1,71 @@ +import { ComponentPublicInstance, nextTick } from 'vue'; +import { DOMWrapper, mount, VueWrapper } from '@vue/test-utils'; +import { Tree } from '../../'; +import { basicData } from './basic-data'; + +describe('Basic tree should include rendering of nested nodes and responses to hover, click and expand/collapse events.', () => { + let wrapper: VueWrapper; + let firstNode: Omit, 'exists'>; + let lastNode: Omit, 'exists'>; + + beforeAll(() => { + wrapper = mount({ + setup() { + return () => { + return ; + }; + }, + }); + + firstNode = wrapper.get('.devui-tree-node:first-child'); + lastNode = wrapper.get('.devui-tree-node:last-child'); + }); + + afterAll(() => { + wrapper.unmount(); + }); + + it('Should render tree container correctly.', () => { + expect(wrapper.classes()).toContain('devui-tree'); + }); + + it('Should render correct number of child nodes.', () => { + expect(wrapper.element.childElementCount).toBe(5); + }); + + it('Should render correct node content.', () => { + expect(firstNode.text()).toBe('Parent node 1'); + expect(lastNode.text()).toBe('Leaf node 2'); + }); + + it('Should render the style of child node correctly.', () => { + const childNodeParent = wrapper.get('.devui-tree-node:nth-child(2)'); + const childNodeLeaf = wrapper.get('.devui-tree-node:nth-child(3)'); + + expect(childNodeParent.attributes('style').indexOf('padding-left: 24px;') > -1).toBe(true); + expect(childNodeLeaf.attributes('style').indexOf('padding-left: 24px;') > -1).toBe(true); + }); + + it.todo('Should render the style of node connection line correctly.'); + + it.todo('The node should be highlighted when clicked.'); + + it.todo('The node should be disabled and unclickable when disabled is set to true.'); + + it('The node should expand and collapse correctly when the expand-collapse button is clicked.', async () => { + // 初始状态,节点是展开的 + expect(firstNode.classes()).toContain('devui-tree-node__open'); + + // 点击之后,节点收起 + await wrapper.get('.devui-tree-node__folder:first-child').trigger('click'); + await nextTick(); + expect(firstNode.classes()).not.toContain('devui-tree-node__open'); + + // 再次点击,节点展开 + await wrapper.get('.devui-tree-node__folder:first-child').trigger('click'); + await nextTick(); + expect(firstNode.classes()).toContain('devui-tree-node__open'); + }); + + it.todo('The node should be disabled and unclickable when disableToggle is set to true.'); +}); diff --git a/packages/devui-vue/devui/tree/__tests__/tree.spec.ts b/packages/devui-vue/devui/tree/__tests__/tree.spec.ts index d9415f0401..a16ee372e0 100644 --- a/packages/devui-vue/devui/tree/__tests__/tree.spec.ts +++ b/packages/devui-vue/devui/tree/__tests__/tree.spec.ts @@ -1,188 +1,24 @@ -import { mount, VueWrapper } from '@vue/test-utils'; -import type { ComponentPublicInstance } from 'vue'; -import { ref, nextTick } from 'vue'; -import DTree from '../src/tree'; - describe('tree', () => { - let wrapper: VueWrapper; - - beforeEach(() => { - const data = ref([ - { - label: 'parent node 1 - expanded', - open: true, - disabled: true, - level: 1, - children: [ - { - label: 'parent node 11 - folded', - level: 2, - children: [ - { - label: 'leaf node 111', - level: 3, - }, - { - label: 'leaf node 112', - level: 3, - }, - { - label: 'leaf node 113', - level: 3, - }, - { - label: 'leaf node 114', - level: 3, - } - ] - }, - { - label: 'parent node 12 - folded', - disableToggle: true, - level: 2, - children: [ - { - label: 'leaf node 121', - level: 3, - }, - { - label: 'leaf node 122', - level: 3, - }, - { - label: 'leaf node 123', - level: 3, - }, - { - label: 'leaf node 124', - level: 3, - } - ] - }, - { - label: 'parent node 13 - without children - dynamic loading', - isParent: true, - level: 2, - } - ] - }, - { - label: 'parent node 2 - folded', - level: 1, - children: [ - { - label: 'parent node 21 - expanded', - open: true, - level: 2, - children: [ - { - label: 'leaf node 211', - level: 3, - }, - { - label: 'leaf node 212', - level: 3, - }, - { - label: 'leaf node 213', - level: 3, - }, - { - label: 'leaf node 214', - level: 3, - } - ] - }, - { - label: 'parent node 22 - folded', - level: 2, - children: [ - { - label: 'leaf node 221', - level: 3, - }, - { - label: 'leaf node 222', - level: 3, - }, - { - label: 'leaf node 223', - level: 3, - }, - { - label: 'leaf node 224', - level: 3, - } - ] - }, - { - label: 'parent node 23 - folded', - level: 2, - children: [ - { - label: 'leaf node 231', - level: 3, - }, - { - label: 'leaf node 232', - level: 3, - }, - { - label: 'leaf node 233', - level: 3, - }, - { - label: 'leaf node 234', - level: 3, - } - ] - } - ] - }, - { - id: 'dynamicNode', - label: 'parent node 3 - without children - dynamic loading', - isParent: true, - level: 1, - data: { - id: 'newChildNode', - name: 'new child node' - } - } - ]); - - wrapper = mount({ - components: { DTree }, - template: ` - - `, - setup () { - return { - data, - }; - } - }); - }); - - it('should render correctly', () => { - expect(wrapper.classes()).toContain('devui-tree'); - expect(wrapper.element.childElementCount).toBe(6); - }); - - it('should expand and collapse correctly', async () => { - const firstNode = wrapper.get('.devui-tree-node:first-child'); - - // 初始状态,节点是展开的 - expect(firstNode.classes()).toContain('devui-tree-node__open'); - - // 点击之后,节点收起 - await wrapper.get('.devui-tree-node__folder:first-child').trigger('click'); - await nextTick(); - expect(firstNode.classes()).not.toContain('devui-tree-node__open'); - - // 再次点击,节点展开 - await wrapper.get('.devui-tree-node__folder:first-child').trigger('click'); - await nextTick(); - expect(firstNode.classes()).toContain('devui-tree-node__open'); - }); + // 测试节点懒加载功能是否正常 + it.todo('should loading child nodes dynamicly when click open button'); + + // 当节点下只有一个子节点时,应该合并这些节点 + it.todo('should merge nodes when there is only one child node'); + + /** + * 测试嵌套节点渲染和基本交互 + * 测试节点懒加载功能是否正常 + * 当节点下只有一个子节点时,应该合并这些节点 + * 节点的勾选功能正常 + * 勾选复选框的禁用状态正常 + * 父子check控制功能正常 + * 自定义图标功能正常 + * 节点的增删改(操作按钮)功能正常 + * loading模板功能正常 + * 搜索过滤功能正常 + * 自定义树中显示和搜索的关键字功能正常 + * 拖拽排序功能正常 + * 虚拟滚动功能正常 + * 无动画功能正常 + */ }); diff --git a/packages/devui-vue/devui/tree/src/assets/close.svg b/packages/devui-vue/devui/tree/src/assets/close.svg deleted file mode 100644 index 2bb8e7f819..0000000000 --- a/packages/devui-vue/devui/tree/src/assets/close.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - diff --git a/packages/devui-vue/devui/tree/src/assets/open.svg b/packages/devui-vue/devui/tree/src/assets/open.svg deleted file mode 100644 index a69af88b16..0000000000 --- a/packages/devui-vue/devui/tree/src/assets/open.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/packages/devui-vue/devui/tree/src/components/icon-close.tsx b/packages/devui-vue/devui/tree/src/components/icon-close.tsx new file mode 100644 index 0000000000..b8e76af6fb --- /dev/null +++ b/packages/devui-vue/devui/tree/src/components/icon-close.tsx @@ -0,0 +1,20 @@ +import { VNodeTypes } from 'vue'; + +export const IconClose = (): VNodeTypes => ( + + + + + + +); diff --git a/packages/devui-vue/devui/tree/src/components/icon-open.tsx b/packages/devui-vue/devui/tree/src/components/icon-open.tsx new file mode 100644 index 0000000000..e0454119b9 --- /dev/null +++ b/packages/devui-vue/devui/tree/src/components/icon-open.tsx @@ -0,0 +1,17 @@ +import { VNodeTypes } from 'vue'; + +export const IconOpen = (): VNodeTypes => ( + + + + + + +); diff --git a/packages/devui-vue/devui/tree/src/tree-types.ts b/packages/devui-vue/devui/tree/src/tree-types.ts index 7ca4f3b9a4..f4f8372824 100644 --- a/packages/devui-vue/devui/tree/src/tree-types.ts +++ b/packages/devui-vue/devui/tree/src/tree-types.ts @@ -1,7 +1,7 @@ import type { PropType, ExtractPropTypes, SetupContext } from 'vue'; export interface TreeItem { - id: string; + id?: string; label: string; isParent?: boolean; level?: number; diff --git a/packages/devui-vue/devui/tree/src/tree.tsx b/packages/devui-vue/devui/tree/src/tree.tsx index b44bfcec68..ec9c77a76e 100644 --- a/packages/devui-vue/devui/tree/src/tree.tsx +++ b/packages/devui-vue/devui/tree/src/tree.tsx @@ -12,8 +12,8 @@ import useChecked from './composables/use-checked'; import useLazy from './composables/use-lazy'; import useOperate from './composables/use-operate'; import useDraggable from './composables/use-draggable'; -import IconOpen from './assets/open.svg'; -import IconClose from './assets/close.svg'; +import { IconOpen } from './components/icon-open'; +import { IconClose } from './components/icon-close'; import NodeContent from './tree-node-content'; import './tree.scss';