From 8eef0777d2fde3544e89af3dc6eaa5e89208d7a0 Mon Sep 17 00:00:00 2001
From: PiePie <45820630+ImaginingMaker@users.noreply.github.com>
Date: Wed, 19 Nov 2025 00:02:18 +0800
Subject: [PATCH] test(radio): improve the formatting and coverage of test
cases
---
.../__snapshots__/radio.test.tsx.snap | 90 +-
.../components/radio/__tests__/radio.test.tsx | 810 +++++++++++-------
2 files changed, 552 insertions(+), 348 deletions(-)
diff --git a/packages/components/radio/__tests__/__snapshots__/radio.test.tsx.snap b/packages/components/radio/__tests__/__snapshots__/radio.test.tsx.snap
index 5592abd32c..c7f6bedf42 100644
--- a/packages/components/radio/__tests__/__snapshots__/radio.test.tsx.snap
+++ b/packages/components/radio/__tests__/__snapshots__/radio.test.tsx.snap
@@ -1,6 +1,6 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`Radio Component > props.checked is equal to true 1`] = `
+exports[`Radio > props > :checked input element 1`] = `
`;
-exports[`Radio Component > props.checked works fine 1`] = `
+exports[`Radio > props > :checked[false] explicit 1`] = `
`;
-exports[`Radio Component > props.checked works fine 2`] = `
+exports[`Radio > props > :checked[true] 1`] = `
`;
-exports[`Radio Component > props.default works fine 1`] = `
+exports[`Radio > props > :default[function] 1`] = `
`;
-exports[`Radio Component > props.disabled works fine 1`] = `
+exports[`Radio > props > :default[slot] 1`] = `
`;
-exports[`Radio Component > props.disabled works fine 2`] = `
+exports[`Radio > props > :disabled[false] explicit 1`] = `
`;
-exports[`Radio Component > slots.default works fine 1`] = `
+exports[`Radio > props > :disabled[true] 1`] = `
`;
-exports[`RadioGroup Component > props.disabled is equal true 1`] = `
+exports[`RadioGroup > props > :disabled with children 1`] = `
@@ -201,6 +201,7 @@ exports[`RadioGroup Component > props.disabled is equal true 1`] = `
>
props.disabled is equal true 1`] = `
>
props.disabled is equal true 1`] = `
class="t-radio__label"
>
-
- Radio3
-
+ Radio3
@@ -251,7 +248,7 @@ exports[`RadioGroup Component > props.disabled is equal true 1`] = `
>
props.disabled is equal true 1`] = `
`;
-exports[`RadioGroup Component > props.disabled is equal true 2`] = `
+exports[`RadioGroup > props > :disabled with options 1`] = `
@@ -307,7 +304,6 @@ exports[`RadioGroup Component > props.disabled is equal true 2`] = `
>
props.disabled is equal true 2`] = `
>
props.disabled is equal true 2`] = `
class="t-radio__label"
>
- Radio3
+
+ Radio3
+
@@ -354,7 +354,7 @@ exports[`RadioGroup Component > props.disabled is equal true 2`] = `
>
props.disabled is equal true 2`] = `
`;
-exports[`RadioGroup Component > props.name is equal to 'custom-radio-name' 1`] = `
+exports[`RadioGroup > props > :name with children 1`] = `
@@ -411,6 +411,7 @@ exports[`RadioGroup Component > props.name is equal to 'custom-radio-name' 1`] =
>
props.name is equal to 'custom-radio-name' 1`] =
>
props.name is equal to 'custom-radio-name' 1`] =
class="t-radio__label"
>
-
- Radio3
-
+ Radio3
@@ -460,7 +457,7 @@ exports[`RadioGroup Component > props.name is equal to 'custom-radio-name' 1`] =
>
props.name is equal to 'custom-radio-name' 1`] =
`;
-exports[`RadioGroup Component > props.name is equal to 'custom-radio-name' 2`] = `
+exports[`RadioGroup > props > :name with options 1`] = `
@@ -517,7 +514,6 @@ exports[`RadioGroup Component > props.name is equal to 'custom-radio-name' 2`] =
>
props.name is equal to 'custom-radio-name' 2`] =
>
props.name is equal to 'custom-radio-name' 2`] =
class="t-radio__label"
>
- Radio3
+
+ Radio3
+
@@ -563,7 +563,7 @@ exports[`RadioGroup Component > props.name is equal to 'custom-radio-name' 2`] =
>
{
- it('props.allowUncheck works fine', async () => {
- const onChangeFn = vi.fn();
- const wrapper = mount();
- wrapper.findComponent(Radio).trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).toHaveBeenCalled();
- expect(onChangeFn.mock.calls[0][0]).toBe(false);
- expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
- });
-
- it('props.checked works fine', () => {
- // checked default value is false
- const wrapper1 = mount();
- expect(wrapper1.classes('t-is-checked')).toBeFalsy();
- // checked = true
- const wrapper2 = mount();
- expect(wrapper2.classes('t-is-checked')).toBeTruthy();
- expect(wrapper2.element).toMatchSnapshot();
- // checked = false
- const wrapper3 = mount();
- expect(wrapper3.classes('t-is-checked')).toBeFalsy();
- expect(wrapper3.element).toMatchSnapshot();
- });
-
- it(`props.checked is equal to true`, () => {
- const wrapper = mount();
- const domWrapper = wrapper.find('input');
- expect(domWrapper.element.checked).toBeTruthy();
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('props.default works fine', () => {
- const wrapper = mount( TNode}>);
- expect(wrapper.find('.custom-node').exists()).toBeTruthy();
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('slots.default works fine', () => {
- const wrapper = mount( TNode }}>);
- expect(wrapper.find('.custom-node').exists()).toBeTruthy();
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('props.disabled works fine', () => {
- // disabled default value is undefined
- const wrapper1 = mount(Text);
- expect(wrapper1.classes('t-is-disabled')).toBeFalsy();
- // disabled = true
- const wrapper2 = mount(Text);
- expect(wrapper2.classes('t-is-disabled')).toBeTruthy();
- expect(wrapper2.element).toMatchSnapshot();
- // disabled = false
- const wrapper3 = mount(Text);
- expect(wrapper3.classes('t-is-disabled')).toBeFalsy();
- expect(wrapper3.element).toMatchSnapshot();
- });
-
- it('props.disabled works fine', async () => {
- const onChangeFn = vi.fn();
- const wrapper = mount(
-
- Text
- ,
- );
- wrapper.findComponent(Radio).trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).not.toHaveBeenCalled();
- });
-
- it('props.name works fine', () => {
- const wrapper = mount().find('input');
- expect(wrapper.attributes('name')).toBe('radio-gender-name');
- });
-
- it('Events.change: checked default value is false, click radio and trigger change', async () => {
- const onChangeFn = vi.fn();
- const wrapper = mount();
- wrapper.find('.t-radio__label').trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).toHaveBeenCalled();
- expect(onChangeFn.mock.calls[0][0]).toBe(true);
- expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
- });
- it('Events.change: checked value is true, without allowUncheck, click radio and can not trigger change', async () => {
- const onChangeFn = vi.fn();
- const wrapper = mount();
- wrapper.find('.t-radio__label').trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).not.toHaveBeenCalled();
- });
-});
-
-describe('RadioGroup Component', () => {
- it('props.allowUncheck works fine', async () => {
- const onChangeFn = vi.fn();
- const wrapper = getRadioGroupDefaultMount({ value: 1, allowUncheck: true }, { onChange: onChangeFn });
- wrapper.find('.t-radio').trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).toHaveBeenCalled();
- expect(onChangeFn.mock.calls[0][0]).toBe(undefined);
- expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
- });
-
- it('props.allowUncheck works fine', async () => {
- const onChangeFn = vi.fn();
- const wrapper = getRadioGroupKidsMount({ value: 1, allowUncheck: true }, { onChange: onChangeFn });
- wrapper.find('.t-radio').trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).toHaveBeenCalled();
- expect(onChangeFn.mock.calls[0][0]).toBe(undefined);
- expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
- });
-
- it('props.disabled is equal true', () => {
- const wrapper = getRadioGroupDefaultMount({ disabled: true });
- expect(wrapper.findAll('.t-radio.t-is-disabled').length).toBe(4);
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('props.disabled is equal true', () => {
- const wrapper = getRadioGroupKidsMount({ disabled: true });
- expect(wrapper.findAll('.t-radio.t-is-disabled').length).toBe(4);
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('Props.disabled: disabled radio can not trigger change', async () => {
- const onChangeFn = vi.fn();
- const wrapper = getRadioGroupDefaultMount({ disabled: true }, { onChange: onChangeFn });
- wrapper.find('.t-radio').trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).not.toHaveBeenCalled();
- });
-
- it('Props.disabled: disabled radio can not trigger change', async () => {
- const onChangeFn = vi.fn();
- const wrapper = getRadioGroupKidsMount({ disabled: true }, { onChange: onChangeFn });
- wrapper.find('.t-radio').trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).not.toHaveBeenCalled();
- });
-
- it(`props.name is equal to 'custom-radio-name'`, () => {
- const wrapper = getRadioGroupDefaultMount({ name: 'custom-radio-name' });
- const domWrapper = wrapper.find('input');
- expect(domWrapper.attributes('name')).toBe('custom-radio-name');
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it(`props.name is equal to 'custom-radio-name'`, () => {
- const wrapper = getRadioGroupKidsMount({ name: 'custom-radio-name' });
- const domWrapper = wrapper.find('input');
- expect(domWrapper.attributes('name')).toBe('custom-radio-name');
- expect(wrapper.element).toMatchSnapshot();
- });
-
- it('props.options works fine. `{".t-radio":4}` should exist', () => {
- const wrapper = getRadioGroupDefaultMount();
- expect(wrapper.findAll('.t-radio').length).toBe(4);
- });
-
- it('props.options works fine. `".custom-node"` should exist', () => {
- const wrapper = getRadioGroupDefaultMount();
- expect(wrapper.find('.custom-node').exists()).toBeTruthy();
- });
-
- it('props.options works fine. `{".t-radio.t-is-disabled":1}` should exist', () => {
- const wrapper = getRadioGroupDefaultMount();
- expect(wrapper.findAll('.t-radio.t-is-disabled').length).toBe(1);
- });
-
- it(`props.value is equal to '2'`, () => {
- const wrapper = getRadioGroupDefaultMount({ value: '2' });
- const domWrapper = wrapper.find('.t-radio.t-is-checked input');
- expect(domWrapper.element.value).toBe('2');
- });
-
- it(`props.value is equal to '2'`, () => {
- const wrapper = getRadioGroupKidsMount({ value: '2' });
- const domWrapper = wrapper.find('.t-radio.t-is-checked input');
- expect(domWrapper.element.value).toBe('2');
- });
+describe('Radio', () => {
+ describe('props', () => {
+ it(':allowUncheck', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = mount();
+ wrapper.findComponent(Radio).trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).toHaveBeenCalled();
+ expect(onChangeFn.mock.calls[0][0]).toBe(false);
+ expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
+ });
- const variantClassNameList = ['t-radio-group__outline', 't-radio-group--primary-filled', 't-radio-group--filled'];
- ['outline', 'primary-filled', 'default-filled'].forEach((item, index) => {
- it(`props.variant is equal to ${item}`, () => {
- const wrapper = mount();
- if (typeof variantClassNameList[index] === 'string') {
- expect(wrapper.classes(variantClassNameList[index])).toBeTruthy();
- } else if (typeof variantClassNameList[index] === 'object') {
- const classNameKey = Object.keys(variantClassNameList[index])[0];
- expect(wrapper.classes(classNameKey)).toBeFalsy();
- }
+ it(':checked[false]', () => {
+ const wrapper = mount();
+ expect(wrapper.classes('t-is-checked')).toBeFalsy();
});
- });
- it('Events.change: default value is 2, trigger change after click', async () => {
- const onChangeFn = vi.fn();
- const wrapper = getRadioGroupDefaultMount({ value: 2 }, { onChange: onChangeFn });
- wrapper.find('.t-radio').trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).toHaveBeenCalled();
- expect(onChangeFn.mock.calls[0][0]).toBe(1);
- expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
- });
- it('Events.change: default value is empty, trigger change after click', async () => {
- const onChangeFn = vi.fn();
- const wrapper = getRadioGroupDefaultMount({}, { onChange: onChangeFn });
- wrapper.find('.t-radio').trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).toHaveBeenCalled();
- expect(onChangeFn.mock.calls[0][0]).toBe(1);
- expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
- });
+ it(':checked[true]', () => {
+ const wrapper = mount();
+ expect(wrapper.classes('t-is-checked')).toBeTruthy();
+ expect(wrapper.element).toMatchSnapshot();
+ });
- it('Events.change: default value is 2, trigger change after click', async () => {
- const onChangeFn = vi.fn();
- const wrapper = getRadioGroupKidsMount({ value: 2 }, { onChange: onChangeFn });
- wrapper.find('.t-radio').trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).toHaveBeenCalled();
- expect(onChangeFn.mock.calls[0][0]).toBe(1);
- expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
- });
- it('Events.change: default value is empty, trigger change after click', async () => {
- const onChangeFn = vi.fn();
- const wrapper = getRadioGroupKidsMount({}, { onChange: onChangeFn });
- wrapper.find('.t-radio').trigger('click');
- await wrapper.vm.$nextTick();
- expect(onChangeFn).toHaveBeenCalled();
- expect(onChangeFn.mock.calls[0][0]).toBe(1);
- expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
- });
-});
+ it(':checked[false] explicit', () => {
+ const wrapper = mount();
+ expect(wrapper.classes('t-is-checked')).toBeFalsy();
+ expect(wrapper.element).toMatchSnapshot();
+ });
-describe('Radio', () => {
- // test props api
- describe(':props', () => {
- it(':checked', () => {
- const wrapper = mount(() => );
- const radio = wrapper.find('.t-radio');
- expect(radio.exists()).toBeTruthy();
- expect(radio.classes()).toContain('t-is-checked');
+ it(':checked input element', () => {
+ const wrapper = mount();
+ const domWrapper = wrapper.find('input');
+ expect(domWrapper.element.checked).toBeTruthy();
+ expect(wrapper.element).toMatchSnapshot();
});
+
it(':defaultChecked', () => {
const wrapper = mount(() => );
const radio = wrapper.find('.t-radio');
expect(radio.exists()).toBeTruthy();
expect(radio.classes()).toContain('t-is-checked');
});
- it(':disabled', () => {
- const wrapper = mount(() => );
- const radio = wrapper.find('.t-radio');
- expect(radio.classes()).toContain('t-is-disabled');
+
+ it(':default[function]', () => {
+ const wrapper = mount( TNode}>);
+ expect(wrapper.find('.custom-node').exists()).toBeTruthy();
+ expect(wrapper.element).toMatchSnapshot();
});
- it(':name', () => {
- const wrapper = mount(() => );
- const input = wrapper.find('.t-radio input');
- expect(input.element.getAttribute('name')).toBe('name');
+
+ it(':default[slot]', () => {
+ const wrapper = mount( TNode }}>);
+ expect(wrapper.find('.custom-node').exists()).toBeTruthy();
+ expect(wrapper.element).toMatchSnapshot();
});
- it(':default', () => {
+
+ it(':default[string]', () => {
const wrapper = mount(() => );
const label = wrapper.find('.t-radio__label');
expect(label.exists()).toBeTruthy();
expect(label.text()).toBe('label');
});
+
+ it(':disabled[false]', () => {
+ const wrapper = mount(Text);
+ expect(wrapper.classes('t-is-disabled')).toBeFalsy();
+ });
+
+ it(':disabled[true]', () => {
+ const wrapper = mount(Text);
+ expect(wrapper.classes('t-is-disabled')).toBeTruthy();
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it(':disabled[false] explicit', () => {
+ const wrapper = mount(Text);
+ expect(wrapper.classes('t-is-disabled')).toBeFalsy();
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it(':disabled prevents onChange', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = mount(
+
+ Text
+ ,
+ );
+ wrapper.findComponent(Radio).trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).not.toHaveBeenCalled();
+ });
+
it(':label', () => {
const wrapper = mount(() => );
const label = wrapper.find('.t-radio__label');
expect(label.exists()).toBeTruthy();
expect(label.text()).toBe('label');
});
- it(':allowUncheck', async () => {
+
+ it(':name', () => {
+ const wrapper = mount().find('input');
+ expect(wrapper.attributes('name')).toBe('radio-gender-name');
+ });
+
+ it(':name attribute', () => {
+ const wrapper = mount(() => );
+ const input = wrapper.find('.t-radio input');
+ expect(input.element.getAttribute('name')).toBe('name');
+ });
+ });
+
+ describe('events', () => {
+ it(':onChange when unchecked', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = mount();
+ wrapper.find('.t-radio__label').trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).toHaveBeenCalled();
+ expect(onChangeFn.mock.calls[0][0]).toBe(true);
+ expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
+ });
+
+ it(':onChange when checked without allowUncheck', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = mount();
+ wrapper.find('.t-radio__label').trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).not.toHaveBeenCalled();
+ });
+
+ it(':onChange with allowUncheck', async () => {
const fn = vi.fn();
const wrapper = mount(() => (
@@ -289,16 +146,6 @@ describe('Radio', () => {
await nextTick();
expect(fn).toBeCalled();
});
- });
- describe(':events', () => {
- it(':onChange', async () => {
- const fn = vi.fn();
- const wrapper = mount(() => label);
- const radio = wrapper.find('.t-radio');
- await radio.trigger('click');
- await nextTick();
- expect(fn).toBeCalled();
- });
it(':onClick', async () => {
const fn = vi.fn();
@@ -311,8 +158,53 @@ describe('Radio', () => {
});
describe('RadioGroup', () => {
- describe(':props', () => {
- it(':disabled', () => {
+ describe('props', () => {
+ it(':allowUncheck with options', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = getRadioGroupDefaultMount({ value: 1, allowUncheck: true }, { onChange: onChangeFn });
+ wrapper.find('.t-radio').trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).toHaveBeenCalled();
+ expect(onChangeFn.mock.calls[0][0]).toBe(undefined);
+ expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
+ });
+
+ it(':allowUncheck with children', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = getRadioGroupKidsMount({ value: 1, allowUncheck: true }, { onChange: onChangeFn });
+ wrapper.find('.t-radio').trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).toHaveBeenCalled();
+ expect(onChangeFn.mock.calls[0][0]).toBe(undefined);
+ expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
+ });
+
+ it(':defaultValue', () => {
+ const defaultValue = ref('1');
+ const wrapper = mount(() => (
+
+ 选项一
+ 选项二
+
+ ));
+ const inputList = wrapper.findAll('.t-radio');
+ expect(inputList[0].classes()).toContain('t-is-checked');
+ expect(inputList[1].classes()).not.toContain('t-is-checked');
+ });
+
+ it(':disabled with options', () => {
+ const wrapper = getRadioGroupDefaultMount({ disabled: true });
+ expect(wrapper.findAll('.t-radio.t-is-disabled').length).toBe(4);
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it(':disabled with children', () => {
+ const wrapper = getRadioGroupKidsMount({ disabled: true });
+ expect(wrapper.findAll('.t-radio.t-is-disabled').length).toBe(4);
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it(':disabled with children (JSX)', () => {
const wrapper = mount(() => (
选项一
@@ -325,7 +217,37 @@ describe('RadioGroup', () => {
});
});
- it(':name', () => {
+ it(':disabled prevents onChange with options', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = getRadioGroupDefaultMount({ disabled: true }, { onChange: onChangeFn });
+ wrapper.find('.t-radio').trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).not.toHaveBeenCalled();
+ });
+
+ it(':disabled prevents onChange with children', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = getRadioGroupKidsMount({ disabled: true }, { onChange: onChangeFn });
+ wrapper.find('.t-radio').trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).not.toHaveBeenCalled();
+ });
+
+ it(':name with options', () => {
+ const wrapper = getRadioGroupDefaultMount({ name: 'custom-radio-name' });
+ const domWrapper = wrapper.find('input');
+ expect(domWrapper.attributes('name')).toBe('custom-radio-name');
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it(':name with children', () => {
+ const wrapper = getRadioGroupKidsMount({ name: 'custom-radio-name' });
+ const domWrapper = wrapper.find('input');
+ expect(domWrapper.attributes('name')).toBe('custom-radio-name');
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it(':name with children (JSX)', () => {
const wrapper = mount(() => (
选项一
@@ -338,32 +260,22 @@ describe('RadioGroup', () => {
});
});
- it(':size', () => {
- const sizeList = ['small', 'large'];
- sizeList.forEach((size) => {
- const wrapper = mount(() => (
-
- 选项一
- 选项二
-
- ));
- expect(wrapper.find('.t-radio-group').classes()).toContain(`t-size-${size.slice(0, 1)}`);
- });
+ it(':options render radios', () => {
+ const wrapper = getRadioGroupDefaultMount();
+ expect(wrapper.findAll('.t-radio').length).toBe(4);
});
- it(':defaultValue', () => {
- const defaultValue = ref('1');
- const wrapper = mount(() => (
-
- 选项一
- 选项二
-
- ));
- const inputList = wrapper.findAll('.t-radio');
- expect(inputList[0].classes()).toContain('t-is-checked');
- expect(inputList[1].classes()).not.toContain('t-is-checked');
+ it(':options with custom node', () => {
+ const wrapper = getRadioGroupDefaultMount();
+ expect(wrapper.find('.custom-node').exists()).toBeTruthy();
+ });
+
+ it(':options with disabled item', () => {
+ const wrapper = getRadioGroupDefaultMount();
+ expect(wrapper.findAll('.t-radio.t-is-disabled').length).toBe(1);
});
- it(':options', () => {
+
+ it(':options with data', () => {
const options = [
{
value: '1',
@@ -383,51 +295,198 @@ describe('RadioGroup', () => {
expect(inputList[1].classes()).not.toContain('t-is-checked');
});
- it(':variant', () => {
- // const variantList = ['outline', 'primary-filled', 'default-filled'];
- const wrapper1 = mount(() => (
-
+ it(':size', () => {
+ const sizeList = ['small', 'large'];
+ sizeList.forEach((size) => {
+ const wrapper = mount(() => (
+
+ 选项一
+ 选项二
+
+ ));
+ expect(wrapper.find('.t-radio-group').classes()).toContain(`t-size-${size.slice(0, 1)}`);
+ });
+ });
+
+ it(':theme[radio]', () => {
+ const wrapper = mount(() => (
+
选项一
选项二
));
- expect(wrapper1.find('.t-radio-group').classes()).toContain(`t-radio-group__outline`);
- const wrapper2 = mount(() => (
-
+ expect(wrapper.findComponent(Radio)).toBeTruthy();
+ });
+
+ it(':theme[button]', () => {
+ const wrapper = mount(() => (
+
选项一
选项二
));
- expect(wrapper2.find('.t-radio-group').classes()).toContain(`t-radio-group--primary-filled`);
- const wrapper3 = mount(() => (
-
+ expect(wrapper.findComponent(RadioButton)).toBeTruthy();
+ });
+
+ it(':theme[button] with options renders RadioButton', () => {
+ const options = [
+ { value: '1', label: '选项一' },
+ { value: '2', label: '选项二' },
+ { value: '3', label: '选项三' },
+ ];
+ const wrapper = mount(() => );
+ const radioButtons = wrapper.findAllComponents(RadioButton);
+ expect(radioButtons.length).toBe(3);
+ expect(radioButtons[0].classes()).toContain('t-is-checked');
+ });
+
+ it(':theme[radio] with options renders Radio', () => {
+ const options = [
+ { value: '1', label: '选项一' },
+ { value: '2', label: '选项二' },
+ ];
+ const wrapper = mount(() => );
+ const radios = wrapper.findAllComponents(Radio);
+ expect(radios.length).toBe(2);
+ });
+
+ it(':options with number or string values', () => {
+ const options = [1, 2, 'three', 4];
+ const wrapper = mount(() => );
+ const radios = wrapper.findAll('.t-radio');
+ expect(radios.length).toBe(4);
+ expect(radios[1].classes()).toContain('t-is-checked');
+ expect(radios[1].text()).toBe('2');
+ });
+
+ it(':variant outline does not render background block', () => {
+ const wrapper = mount(() => (
+
+ 选项一
+ 选项二
+
+ ));
+ expect(wrapper.find('.t-radio-group__bg-block').exists()).toBeFalsy();
+ });
+
+ it(':value with options', () => {
+ const wrapper = getRadioGroupDefaultMount({ value: '2' });
+ const domWrapper = wrapper.find('.t-radio.t-is-checked input');
+ expect(domWrapper.element.value).toBe('2');
+ });
+
+ it(':value with children', () => {
+ const wrapper = getRadioGroupKidsMount({ value: '2' });
+ const domWrapper = wrapper.find('.t-radio.t-is-checked input');
+ expect(domWrapper.element.value).toBe('2');
+ });
+
+ it(':variant[outline]', () => {
+ const wrapper = mount();
+ expect(wrapper.classes('t-radio-group__outline')).toBeTruthy();
+ });
+
+ it(':variant[primary-filled]', () => {
+ const wrapper = mount();
+ expect(wrapper.classes('t-radio-group--primary-filled')).toBeTruthy();
+ });
+
+ it(':variant[default-filled]', () => {
+ const wrapper = mount();
+ expect(wrapper.classes('t-radio-group--filled')).toBeTruthy();
+ });
+
+ it(':variant with children (outline)', () => {
+ const wrapper = mount(() => (
+
选项一
选项二
));
- expect(wrapper3.find('.t-radio-group').classes()).toContain(`t-radio-group--filled`);
+ expect(wrapper.find('.t-radio-group').classes()).toContain(`t-radio-group__outline`);
});
- it(':theme', () => {
+
+ it(':variant with children (primary-filled)', () => {
const wrapper = mount(() => (
-
+
选项一
选项二
));
- expect(wrapper.findComponent(Radio)).toBeTruthy();
- const wrapper2 = mount(() => (
-
+ expect(wrapper.find('.t-radio-group').classes()).toContain(`t-radio-group--primary-filled`);
+ });
+
+ it(':variant with children (default-filled)', () => {
+ const wrapper = mount(() => (
+
选项一
选项二
));
+ expect(wrapper.find('.t-radio-group').classes()).toContain(`t-radio-group--filled`);
+ });
- expect(wrapper2.findComponent(RadioButton)).toBeTruthy();
+ it(':variant filled bar style calculation', async () => {
+ const value = ref('1');
+ const wrapper = mount(() => (
+
+ 选项一
+ 选项二
+
+ ));
+ await nextTick();
+ const bgBlock = wrapper.find('.t-radio-group__bg-block');
+ expect(bgBlock.exists()).toBeTruthy();
+
+ // Change value to trigger bar style recalculation
+ value.value = '2';
+ await nextTick();
+ expect(bgBlock.exists()).toBeTruthy();
});
});
- describe(':events', () => {
- it(':onChange', async () => {
+ describe('events', () => {
+ it(':onChange with options (value: 2)', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = getRadioGroupDefaultMount({ value: 2 }, { onChange: onChangeFn });
+ wrapper.find('.t-radio').trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).toHaveBeenCalled();
+ expect(onChangeFn.mock.calls[0][0]).toBe(1);
+ expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
+ });
+
+ it(':onChange with options (empty value)', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = getRadioGroupDefaultMount({}, { onChange: onChangeFn });
+ wrapper.find('.t-radio').trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).toHaveBeenCalled();
+ expect(onChangeFn.mock.calls[0][0]).toBe(1);
+ expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
+ });
+
+ it(':onChange with children (value: 2)', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = getRadioGroupKidsMount({ value: 2 }, { onChange: onChangeFn });
+ wrapper.find('.t-radio').trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).toHaveBeenCalled();
+ expect(onChangeFn.mock.calls[0][0]).toBe(1);
+ expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
+ });
+
+ it(':onChange with children (empty value)', async () => {
+ const onChangeFn = vi.fn();
+ const wrapper = getRadioGroupKidsMount({}, { onChange: onChangeFn });
+ wrapper.find('.t-radio').trigger('click');
+ await wrapper.vm.$nextTick();
+ expect(onChangeFn).toHaveBeenCalled();
+ expect(onChangeFn.mock.calls[0][0]).toBe(1);
+ expect(onChangeFn.mock.calls[0][1].e.type).toBe('click');
+ });
+
+ it(':onChange with v-model', async () => {
const defaultValue = ref('1');
const fn = vi.fn();
const wrapper = mount(() => (
@@ -445,3 +504,148 @@ describe('RadioGroup', () => {
});
});
});
+
+describe('RadioButton', () => {
+ describe('props', () => {
+ it(':defaultChecked', () => {
+ const wrapper = mount(Button);
+ expect(wrapper.text()).toBe('Button');
+ });
+
+ it(':disabled', () => {
+ const wrapper = mount(Disabled Button);
+ expect(wrapper.find('.t-radio-button').classes()).toContain('t-is-disabled');
+ });
+ });
+});
+
+describe('RadioGroup Keyboard', () => {
+ it('keyboard Enter key to select radio', async () => {
+ const wrapper = mount(() => (
+
+ 选项一
+ 选项二
+ 选项三
+
+ ));
+ await nextTick();
+
+ const radioList = wrapper.findAll('.t-radio');
+ await radioList[1].trigger('keydown', { key: 'Enter' });
+ await nextTick();
+ expect(radioList[1].classes()).toContain('t-is-checked');
+ });
+
+ it('keyboard with allowUncheck', async () => {
+ const wrapper = mount(() => (
+
+ 选项一
+ 选项二
+
+ ));
+ await nextTick();
+
+ const radioList = wrapper.findAll('.t-radio');
+ expect(radioList[0].classes()).toContain('t-is-checked');
+
+ // Press Enter on checked radio with allowUncheck should uncheck it
+ await radioList[0].trigger('keydown', { key: 'Enter' });
+ await nextTick();
+ expect(radioList[0].classes()).not.toContain('t-is-checked');
+ });
+
+ it('keyboard with number value', async () => {
+ const wrapper = mount(() => (
+
+ 选项一
+ 选项二
+
+ ));
+ await nextTick();
+
+ const radioList = wrapper.findAll('.t-radio');
+ await radioList[0].trigger('keydown', { key: 'Enter' });
+ await nextTick();
+ expect(radioList[0].classes()).toContain('t-is-checked');
+ });
+
+ it('keyboard with boolean value', async () => {
+ const wrapper = mount(() => (
+
+ True
+ False
+
+ ));
+ await nextTick();
+
+ const radioList = wrapper.findAll('.t-radio');
+ await radioList[0].trigger('keydown', { key: 'Enter' });
+ await nextTick();
+ expect(radioList[0].classes()).toContain('t-is-checked');
+ });
+
+ it('keyboard with string value', async () => {
+ const wrapper = mount(() => (
+
+ 选项一
+ 选项二
+
+ ));
+ await nextTick();
+
+ const radioList = wrapper.findAll('.t-radio');
+ await radioList[1].trigger('keydown', { key: 'Enter' });
+ await nextTick();
+ expect(radioList[1].classes()).toContain('t-is-checked');
+ });
+
+ it('keyboard with quoted string value', async () => {
+ const fn = vi.fn();
+ const wrapper = mount(() => (
+
+ Quoted
+ Normal
+
+ ));
+ await nextTick();
+
+ const radioList = wrapper.findAll('.t-radio');
+ await radioList[0].trigger('keydown', { key: 'Enter' });
+ await nextTick();
+ expect(fn).toHaveBeenCalled();
+ });
+
+ it('keyboard event should not trigger when target has no input', async () => {
+ const wrapper = mount(() => (
+
+ 选项一
+ 选项二
+
+ ));
+ await nextTick();
+
+ // Trigger keydown on the group itself, not on radio
+ await wrapper.find('.t-radio-group').trigger('keydown', { key: 'Enter' });
+ await nextTick();
+
+ // Value should remain unchanged
+ const radioList = wrapper.findAll('.t-radio');
+ expect(radioList[0].classes()).toContain('t-is-checked');
+ });
+
+ it('keyboard with non-checked keys should not trigger', async () => {
+ const fn = vi.fn();
+ const wrapper = mount(() => (
+
+ 选项一
+ 选项二
+
+ ));
+ await nextTick();
+
+ const radioList = wrapper.findAll('.t-radio');
+ await radioList[0].trigger('keydown', { key: 'ArrowDown' });
+ await nextTick();
+ expect(fn).not.toHaveBeenCalled();
+ });
+});