Skip to content

Commit

Permalink
test: add more test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Barrior committed Jan 23, 2024
1 parent 5632ffc commit 477938a
Show file tree
Hide file tree
Showing 8 changed files with 537 additions and 17 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"Immer",
"Popconfirm",
"shenzhen",
"stylelint"
"stylelint",
"testid"
],
"stylelint.validate": ["css", "less", "postcss", "scss"],
"editor.formatOnSave": true
Expand Down
104 changes: 90 additions & 14 deletions test/core-react/@helpers/renderers.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,52 @@
import type { IRenderers, ISchema } from '@core-react/index'
import type { IObjectSchema, IRenderers, ISchema } from '@core-react/index'
import { RendererIterator } from '@core-react/index'
import classNames from 'classnames'

const renderers: IRenderers<any, ISchema> = {
Object: {
formItem: ({ schema, path, objectStyle }) => {
return (
<div {...schema.renderOptions}>
<div>{schema.title}</div>
<div style={objectStyle}>
<RendererIterator schema={schema as IObjectSchema} path={path} />
</div>
</div>
)
},
},
InputText: {
component: ({ schema, value, disabled, readonly, onChange }) => {
if (readonly) {
return <div className="input-text is-readonly">{value}</div>
}
component: ({ schema, value, onChange }) => {
return (
<input
className={classNames('input-text', { 'is-disabled': disabled })}
className="input-text"
{...schema.renderOptions}
value={value ?? ''}
onChange={(e) => onChange(e.target.value)}
/>
)
},
readonlyComponent: ({ schema, value }) => (
<div {...schema.renderOptions} className="input-text is-readonly">
{value}
</div>
),
disabledComponent: ({ schema, value }) => (
<input
{...schema.renderOptions}
className="input-text is-disabled"
value={value ?? ''}
/>
),
},
InputNumber: {
component: ({ schema, value, disabled, readonly, onChange }) => {
if (readonly) {
return <div className="input-number is-readonly">{value}</div>
return (
<div {...schema.renderOptions} className="input-number is-readonly">
{value}
</div>
)
}
return (
<input
Expand All @@ -35,7 +61,11 @@ const renderers: IRenderers<any, ISchema> = {
TextArea: {
component: ({ schema, value, disabled, readonly, onChange }) => {
if (readonly) {
return <div className="textarea is-readonly">{value}</div>
return (
<div {...schema.renderOptions} className="textarea is-readonly">
{value}
</div>
)
}
return (
<textarea
Expand All @@ -49,11 +79,8 @@ const renderers: IRenderers<any, ISchema> = {
},
},
// 输出警告的 InputText 渲染器
WarningInputText: {
component: ({ schema, value, disabled, readonly, onChange }) => {
if (readonly) {
return <div className="input-text is-readonly">{value}</div>
}
InputTextWithWarning: {
component: ({ schema, value, disabled, onChange }) => {
return (
<input
className={classNames('input-text', { 'is-disabled': disabled })}
Expand All @@ -63,13 +90,62 @@ const renderers: IRenderers<any, ISchema> = {
/>
)
},
readonlyComponent: ({ schema, value }) => (
<div {...schema.renderOptions} className="input-text is-readonly">
{value}
</div>
),
validator: () => {
return {
status: 'warning',
message: 'warning-message-from-WarningInputText',
message: 'warning-message-from-InputTextWithWarning',
}
},
},
// onChange 带 extra 信息的 InputText 渲染器
InputTextWithChangeExtra: {
component: ({ schema, value, disabled, onChange }) => {
return (
<input
className={classNames('input-text', { 'is-disabled': disabled })}
{...schema.renderOptions}
value={value ?? ''}
onChange={(e) =>
onChange(e.target.value, {
extra: '我是额外的数据',
})
}
/>
)
},
readonlyComponent: ({ schema, value }) => (
<div {...schema.renderOptions} className="input-text is-readonly">
{value}
</div>
),
},
// onChange 不触发「校验器」的 InputText 渲染器
InputTextWithoutTriggerValidator: {
component: ({ schema, value, disabled, onChange }) => {
return (
<input
className={classNames('input-text', { 'is-disabled': disabled })}
{...schema.renderOptions}
value={value ?? ''}
onChange={(e) =>
onChange(e.target.value, {
triggerValidator: false,
})
}
/>
)
},
readonlyComponent: ({ schema, value }) => (
<div {...schema.renderOptions} className="input-text is-readonly">
{value}
</div>
),
},
}

export default renderers
53 changes: 53 additions & 0 deletions test/core-react/disabled.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { wrapRootSchema } from '@test/@helpers/schema'
import { render, screen } from '@testing-library/react'

import CompletedCore from './@helpers/CompletedCore'

const schema = wrapRootSchema({
width: {
title: '宽度',
renderType: 'InputNumber',
renderOptions: {
'data-testid': 'tid-width',
},
disabled: true,
},
height: {
title: '高度',
renderType: 'InputNumber',
renderOptions: {
'data-testid': 'tid-height',
},
},
nested: {
title: 'object-title',
renderType: 'Object',
properties: {
left: {
title: '水平位置',
renderType: 'InputNumber',
renderOptions: {
'data-testid': 'tid-left',
},
},
},
},
})

describe('disabled 验证', () => {
test('局部只读态,应该只影响自身', async () => {
render(<CompletedCore schema={schema} />)
const elem = screen.queryByTestId('tid-width')
expect(elem).toBeInTheDocument()
expect(elem?.classList.contains('is-disabled')).toBeTruthy()
})

test('全局只读态,应该影响所有的表单项', async () => {
render(<CompletedCore schema={schema} disabled />)
const formItems = ['width', 'height', 'left']
formItems.forEach((name) => {
const elem = screen.queryByTestId(`tid-${name}`)
expect(elem?.classList.contains('is-disabled')).toBeTruthy()
})
})
})
118 changes: 118 additions & 0 deletions test/core-react/onChange.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { wrapRootSchema } from '@test/@helpers/schema'
import { fireEvent, render, screen } from '@testing-library/react'

import CompletedCore from './@helpers/CompletedCore'

const schema = wrapRootSchema({
width: {
title: '宽度',
renderType: 'InputNumber',
renderOptions: {
'data-testid': 'tid-width',
},
required: true,
},
height: {
title: '高度',
renderType: 'InputNumber',
renderOptions: {
'data-testid': 'tid-height',
},
},
remark: {
title: '备注',
renderType: 'InputTextWithWarning',
renderOptions: {
'data-testid': 'tid-remark',
},
},
extra: {
title: '携带额外信息',
renderType: 'InputTextWithChangeExtra',
renderOptions: {
'data-testid': 'tid-extra',
},
},
withoutValidator: {
title: '不要触发校验器',
renderType: 'InputTextWithoutTriggerValidator',
renderOptions: {
'data-testid': 'tid-without-validator',
},
},
nested: {
title: 'object-title',
renderType: 'Object',
properties: {
left: {
title: '水平位置',
renderType: 'InputNumber',
renderOptions: {
'data-testid': 'tid-left',
},
},
},
},
})

describe('onChange 验证', () => {
test('input 输入内容后,onChange 回调值应该一致', async () => {
const onChange = jest.fn()
render(<CompletedCore schema={schema} onChange={onChange} />)

const inputElem = screen.queryByTestId('tid-width')
expect(inputElem).toBeInTheDocument()

fireEvent.change(inputElem!, { target: { value: '800' } })
expect(onChange).toBeCalledWith(
{ width: 800 },
{ path: ['width'], sPath: 'width', value: 800 }
)
})

test('对象嵌套的 input 输入内容后,onChange 回调值应该一致', async () => {
const onChange = jest.fn()
render(<CompletedCore schema={schema} onChange={onChange} />)

const inputElem = screen.queryByTestId('tid-left')
expect(inputElem).toBeInTheDocument()

fireEvent.change(inputElem!, { target: { value: '800' } })
expect(onChange).toBeCalledWith(
{ nested: { left: 800 } },
{ path: ['nested', 'left'], sPath: 'nested.left', value: 800 }
)
})

test('渲染器 onChange 带 extra 属性,Core onChange 回调值应该存在 extra 且数据一致', async () => {
const onChange = jest.fn()
render(<CompletedCore schema={schema} onChange={onChange} />)

const inputElem = screen.queryByTestId('tid-extra')
expect(inputElem).toBeInTheDocument()

const inputContent = '我是输入的内容'
fireEvent.change(inputElem!, { target: { value: inputContent } })
expect(onChange).toBeCalledWith(
{ extra: inputContent },
{ path: ['extra'], sPath: 'extra', value: inputContent, extra: '我是额外的数据' }
)
})

test('渲染器 onChange 的 triggerValidator 为 false,则不触发此次校验器', async () => {
const onChange = jest.fn()
render(<CompletedCore schema={schema} onChange={onChange} />)

const inputElem = screen.queryByTestId('tid-without-validator')
expect(inputElem).toBeInTheDocument()

const inputContent = '我是输入的内容'
fireEvent.change(inputElem!, { target: { value: inputContent } })
expect(onChange).toBeCalledWith(
{ withoutValidator: inputContent },
{ path: ['withoutValidator'], sPath: 'withoutValidator', value: inputContent }
)

// 校验状态无法验证,因为组件不会被重新渲染
})
})
Loading

0 comments on commit 477938a

Please sign in to comment.