From a7cd89f6a457c2b01cb1ddee0cbd61676773e2e8 Mon Sep 17 00:00:00 2001 From: azhe Date: Tue, 22 Nov 2022 16:46:14 +0800 Subject: [PATCH] Test/form (#1820) * feat: set default stackblitz url * test: add form test * fix: getComputedStyle error * chore: remove useless log * test: add form test * test: add grid test * test: add layout test * test: message plugin test * test: add rate test * test: add space test * test: add steps test * feat: update common --- script/test/setup.js | 5 + src/drawer/__tests__/index.test.jsx | 1 - .../__snapshots__/index.test.jsx.snap | 118 +++++++ src/form/__tests__/index.test.jsx | 299 +++++++++++++++++- src/form/_example/base.vue | 2 +- src/grid/__tests__/index.test.jsx | 285 +++++++++++++++++ src/layout/__tests__/index.test.jsx | 105 ++++++ src/message/__tests__/index.test.jsx | 14 +- src/rate/__tests__/index.test.jsx | 43 +++ src/space/__tests__/index.test.jsx | 81 +++++ src/steps/__tests__/index.test.jsx | 278 +++++++++++++++- 11 files changed, 1202 insertions(+), 29 deletions(-) create mode 100644 src/form/__tests__/__snapshots__/index.test.jsx.snap create mode 100644 src/grid/__tests__/index.test.jsx create mode 100644 src/layout/__tests__/index.test.jsx create mode 100644 src/rate/__tests__/index.test.jsx create mode 100644 src/space/__tests__/index.test.jsx diff --git a/script/test/setup.js b/script/test/setup.js index 47d3edd49..356691167 100644 --- a/script/test/setup.js +++ b/script/test/setup.js @@ -2,6 +2,11 @@ import Vue from 'vue'; import VueCompositionAPI from '@vue/composition-api'; import TDesign from '@/src/index'; +// https://github.com/nickcolley/jest-axe/issues/147#issuecomment-758804533 +// fix error when call computedStyle(elt, pseudoElt) +const { getComputedStyle } = window; +window.getComputedStyle = (elt) => getComputedStyle(elt); + Vue.config.productionTip = true; Vue.config.devtools = false; diff --git a/src/drawer/__tests__/index.test.jsx b/src/drawer/__tests__/index.test.jsx index ae0937a64..35dc6f1c8 100644 --- a/src/drawer/__tests__/index.test.jsx +++ b/src/drawer/__tests__/index.test.jsx @@ -202,7 +202,6 @@ describe('Drawer', () => { }); await nextTick(); const btn = wrapper.find('.t-drawer__confirm'); - console.log('onConfirm', btn); await btn.trigger('click'); expect(fn).toBeCalled(); }); diff --git a/src/form/__tests__/__snapshots__/index.test.jsx.snap b/src/form/__tests__/__snapshots__/index.test.jsx.snap new file mode 100644 index 000000000..c519e71db --- /dev/null +++ b/src/form/__tests__/__snapshots__/index.test.jsx.snap @@ -0,0 +1,118 @@ +// Vitest Snapshot v1 + +exports[`Form > @event > validate 1`] = ` +{ + "firstError": "姓名必填", + "validateResult": { + "age": [ + { + "message": "age必填", + "required": true, + "result": false, + }, + ], + "name": [ + { + "message": "姓名必填", + "required": true, + "result": false, + }, + ], + }, +} +`; + +exports[`Form > @event > validate 2`] = ` +{ + "firstError": "姓名必填", + "validateResult": { + "age": [ + { + "message": "age必填", + "required": true, + "result": false, + }, + ], + "name": [ + { + "message": "姓名必填", + "required": true, + "result": false, + }, + ], + }, +} +`; + +exports[`Form > @event > validate 3`] = ` +{ + "firstError": "姓名必填", + "validateResult": { + "age": [ + { + "message": "age必填", + "required": true, + "result": false, + }, + ], + "name": [ + { + "message": "姓名必填", + "required": true, + "result": false, + }, + ], + }, +} +`; + +exports[`Form > @event > validate 4`] = ` +{ + "firstError": "姓名必填", + "validateResult": { + "age": [ + { + "message": "age必填", + "required": true, + "result": false, + }, + ], + "name": [ + { + "message": "姓名必填", + "required": true, + "result": false, + }, + ], + }, +} +`; + +exports[`Form > function > validate 1`] = ` +{ + "age": [ + { + "message": "age必填", + "required": true, + "result": false, + "trigger": "blur", + }, + ], + "name": [ + { + "message": "姓名必填", + "required": true, + "result": false, + "trigger": "blur", + }, + ], +} +`; + +exports[`Form > function > validate 2`] = ` +WrapperArray { + "selector": ".t-input__extra", +} +`; + +exports[`Form > function > validate 3`] = `true`; diff --git a/src/form/__tests__/index.test.jsx b/src/form/__tests__/index.test.jsx index 6f6869e50..0cb167a9a 100644 --- a/src/form/__tests__/index.test.jsx +++ b/src/form/__tests__/index.test.jsx @@ -1,30 +1,303 @@ import { mount } from '@vue/test-utils'; -import Form from '@/src/form/index.ts'; +import { CloseCircleFilledIcon, InfoCircleIcon } from 'tdesign-icons-vue'; +import { FormItem, Form } from '../index.ts'; +import { Input } from '@/src/index.ts'; + +const delay = (time = 0) => new Promise((res, rej) => { + setTimeout(() => { + res(); + }, time); +}); // every component needs four parts: props/events/slots/functions. describe('Form', () => { // test props api describe(':props', () => { - it('', () => { + it(':labelAlign', async () => { + let wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + // Form labelAlign default value: right + expect(wrapper.find('.t-form__label').classes('t-form__label--right')).eq(true); + + wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + expect(wrapper.find('.t-form__label').classes('t-form__label--top')).eq(true); + + wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + expect(wrapper.find('.t-form__label').classes('t-form__label--left')).eq(true); + }); + + it(':labelWidth', async () => { + let wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + + expect(wrapper.find('.t-form__label').element.style.width).eq('100px'); + expect(wrapper.find('.t-form__controls').element.style.marginLeft).eq('100px'); + + wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + expect(wrapper.find('.t-form__label').element.style.width).eq('200px'); + expect(wrapper.find('.t-form__controls').element.style.marginLeft).eq('200px'); + }); + + it(':layout', async () => { + let wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + expect(wrapper.find('.t-form').classes('t-form-inline')).eq(false); + + wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + expect(wrapper.find('.t-form').classes('t-form-inline')).eq(true); + }); + + it(':colon', async () => { + const wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + expect(getComputedStyle(wrapper.find('label').element, '::after').content).eq(''); + }); + + it(':showErrorMessage', async () => { + const rules = { + name: [{ required: true, message: '姓名必填' }], + }; + const formData = { + name: '', + }; const wrapper = mount({ render() { - return
; + return ( +
+ + + +
+ ); }, }); - expect(wrapper.exists()).toBe(true); + const formComp = wrapper.findComponent(Form); + await formComp.vm.validate(); + expect(wrapper.find('.t-input__extra').text()).eq('姓名必填'); + }); + + it(':resetType', async () => { + const rules = { + name: [{ required: true }], + }; + const formData = { + name: 'defaultName', + }; + + const wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + + const form = wrapper.findComponent(Form); + + expect(formData.name).eq('defaultName'); + form.vm.reset(); + expect(formData.name).eq(''); + }); + + it(':statusIcon', async () => { + const rules = { + name: [{ required: true }], + }; + const formData = { + name: '', + }; + + let wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + + let form = wrapper.findComponent(Form); + + await form.vm.validate(); + expect(form.findComponent(CloseCircleFilledIcon).exists()).eq(true); + + // function + wrapper = mount({ + render() { + return ( +
}> + + + + + ); + }, + }); + + form = wrapper.findComponent(Form); + await form.vm.validate(); + expect(form.findComponent(InfoCircleIcon).exists()).eq(true); }); }); // test events - // describe('@event', () => {}); + describe('@event', () => { + it('validate', async () => { + const rules = { + name: [{ required: true, message: '姓名必填' }], + age: [{ required: true }], + }; + const data = { + name: '', + age: undefined, + }; + const onValidate = vi.fn(); + const wrapper = mount({ + render() { + return ( +
+ + + + + + +
+ ); + }, + }); + + const form = wrapper.findComponent(Form); + expect(onValidate).not.toBeCalled(); + + await form.vm.validate(); + expect(onValidate).toHaveBeenCalledTimes(1); + expect(onValidate.mock.calls[0][0]).toMatchSnapshot(); + + form.vm.submit(); + await delay(); + expect(onValidate).toHaveBeenCalledTimes(2); + expect(onValidate.mock.calls[1][0]).toMatchSnapshot(); + + data.name = 'test'; + await form.vm.validate(); + expect(onValidate.mock.calls[2][0]).toMatchSnapshot(); - // test slots - // describe('', () => { - // it('', () => {}); - // }); + data.age = 18; + await form.vm.validate(); + expect(onValidate.mock.calls[3][0]).toMatchSnapshot(); + }); + + it('reset', async () => { + const onReset = vi.fn(); + const rules = { + name: [{ required: true }], + }; + const data = { + name: '', + }; + + const wrapper = mount({ + render() { + return ( +
+ + + +
+ ); + }, + }); + + const form = wrapper.findComponent(Form); + expect(onReset).not.toBeCalled(); - // test exposure function - // describe('function', () => { - // it('', () => {}); - // }); + await form.trigger('reset'); + expect(onReset).toHaveBeenCalledTimes(1); + expect(onReset.mock.calls[0][0].e).toBeInstanceOf(Event); + }); + }); }); diff --git a/src/form/_example/base.vue b/src/form/_example/base.vue index 0591f3ef3..46105d7e4 100644 --- a/src/form/_example/base.vue +++ b/src/form/_example/base.vue @@ -1,5 +1,5 @@