From d5d731eb5705addcc0e5e2a8034960d8fe3e8eb9 Mon Sep 17 00:00:00 2001 From: GweesinChan Date: Fri, 7 Mar 2025 20:56:41 +0800 Subject: [PATCH 1/2] fix(ip-address): fix IPv6 display error when ipValidator not true --- packages/renderless/src/ip-address/index.ts | 45 +++++++++---------- .../ip-address/__tests__/ip-address.test.tsx | 20 ++++++++- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/packages/renderless/src/ip-address/index.ts b/packages/renderless/src/ip-address/index.ts index 1fa05b1771..43aede9267 100644 --- a/packages/renderless/src/ip-address/index.ts +++ b/packages/renderless/src/ip-address/index.ts @@ -89,32 +89,31 @@ export const getValue = export const setValue = ({ api, props, state }: { api: IIpAddressApi; props: IIpAddressProps; state: IIpAddressState }) => (value: string) => { - if (value) { - /* istanbul ignore else */ - if (api?.ipValidator?.(value)) { - if (api.isIP6(props.type)) { - state.address = value.split(':').map((item) => ({ value: item })) - if (state.address.length < 8) { - let insertIndex = 0 - state.address.forEach((item, index) => { - if (item.value === '') { - item.value = '0000' - insertIndex = index - } - }) - for (let i = 0; i <= 8 - state.address.length; i++) { - state.address.splice(insertIndex, 0, { value: '0000' }) - } - } - } else { - state.address = value.split('.').map((item) => ({ value: item })) + if (!value || !api?.ipValidator?.(value)) { + const createValue = () => ({ value: '' }) + state.address = api.isIP6(props.type) + ? Array.from({ length: 8 }, createValue) + : Array.from({ length: 4 }, createValue) + + return + } + + if (api.isIP6(props.type)) { + state.address = value.split(':').map((item) => ({ value: item })) + if (state.address.length < 8) { + const missingCount = 8 - state.address.length + const emptyIndex = state.address.findIndex((item) => item.value === '') + const insertIndex = emptyIndex >= 0 ? emptyIndex : 0 + + if (emptyIndex >= 0) { + state.address[emptyIndex].value = '0000' } + + const newItems = Array(missingCount).fill({ value: '0000' }) + state.address.splice(insertIndex, 0, ...newItems) } } else { - const createValue = () => ({ value: '' }) - state.address = api.isIP6(props.type) - ? new Array(8).fill('').map(createValue) - : new Array(4).fill('').map(createValue) + state.address = value.split('.').map((item) => ({ value: item })) } } diff --git a/packages/vue/src/ip-address/__tests__/ip-address.test.tsx b/packages/vue/src/ip-address/__tests__/ip-address.test.tsx index 0cc90ecce3..761dbe4afd 100644 --- a/packages/vue/src/ip-address/__tests__/ip-address.test.tsx +++ b/packages/vue/src/ip-address/__tests__/ip-address.test.tsx @@ -24,6 +24,22 @@ describe('PC Mode', () => { test.todo('value ,设置文本显示的默认值') + test('invalid value in ipv6', async () => { + value = '127.0.0.1' + const wrapper = mount(() => ) + const values = wrapper.findAll('input').map((inputEl) => inputEl.element.value) + expect(values).toHaveLength(8) + expect(values).toEqual(Array.from({ length: 8 }, () => '')) + }) + + test('invalid value in ipv4', async () => { + value = 'fe80::204:61ff:fe9d:f156' + const wrapper = mount(() => ) + const values = wrapper.findAll('input').map((inputEl) => inputEl.element.value) + expect(values).toHaveLength(4) + expect(values).toEqual(Array.from({ length: 4 }, () => '')) + }) + // slots test('default slot', async () => { const wrapper = mount(() => ( @@ -32,7 +48,7 @@ describe('PC Mode', () => { v-slots={{ default: () => -- }} - > + /> )) expect(wrapper.find('i').text()).toBe('--') }) @@ -40,7 +56,7 @@ describe('PC Mode', () => { // events test('events', async () => { const focus = vi.fn() - const wrapper = mount(() => ) + const wrapper = mount(() => ) await wrapper.find('input').trigger('focus') await nextTick() expect(focus).toHaveBeenCalled() From 58ba9c97997a396de67cd47f559781a2606236a3 Mon Sep 17 00:00:00 2001 From: GweesinChan Date: Fri, 7 Mar 2025 21:13:01 +0800 Subject: [PATCH 2/2] test(ip-address): enhance tests --- .../ip-address/__tests__/ip-address.test.tsx | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/packages/vue/src/ip-address/__tests__/ip-address.test.tsx b/packages/vue/src/ip-address/__tests__/ip-address.test.tsx index 761dbe4afd..d25751040a 100644 --- a/packages/vue/src/ip-address/__tests__/ip-address.test.tsx +++ b/packages/vue/src/ip-address/__tests__/ip-address.test.tsx @@ -2,6 +2,7 @@ import { mountPcMode } from '@opentiny-internal/vue-test-utils' import { describe, expect, test, vi } from 'vitest' import IpAddress from '@opentiny/vue-ip-address' import { nextTick } from 'vue' +import { iconBoat } from '@opentiny/vue-icon' let value = '' @@ -14,15 +15,47 @@ describe('PC Mode', () => { expect(wrapper.find('input').attributes()).toHaveProperty('readonly') }) - test.todo('delimiter ,设置IP段之间的分隔符,默认为 "." ') + describe('delimiter ,设置IP段之间的分隔符', () => { + test('默认为 "." ', async () => { + const wrapper = mount(() => ) + expect(wrapper.findAll('svg')).toHaveLength(3) + }) - test.todo('size ,设置组件大小;该属性的可选值为 medium / small / mini') + test('设置为 "-" ', async () => { + const wrapper = mount(() => ( + + - + + )) + expect(wrapper.findAll('span').map((i) => i.text())).toEqual(['-', '-', '-']) + }) - test.todo('disabled ,设置文本的禁用属性,默认为 false ') + test('设置为 icon', async () => { + const IconBoat = iconBoat() + const wrapper = mount(() => ) + expect(wrapper.findAll('svg')).toHaveLength(3) + }) + }) + + describe('size, 设置组件大小', () => { + ;['medium', 'small', 'mini'].forEach((size) => { + test(size, async () => { + const wrapper = mount(() => ) + expect(wrapper.find('.tiny-ip-address__input').classes()).toContain(size) + }) + }) + }) - test.todo('type ,设置IpAddress框的类型,默认是IPv4,当为IPv6时,只有一个IP端输入框,无分隔符') + test('disabled ,设置文本的禁用属性,默认为 false ', async () => { + const wrapper = mount(() => ) + expect(wrapper.find('input').attributes()).toHaveProperty('disabled') + }) - test.todo('value ,设置文本显示的默认值') + test('value ,设置文本显示的默认值', async () => { + value = '127.0.0.1' + const wrapper = mount(() => ) + expect(wrapper.findAll('input').map((inputEl) => inputEl.element.value)).toEqual(['127', '0', '0', '1']) + }) test('invalid value in ipv6', async () => { value = '127.0.0.1' @@ -40,7 +73,6 @@ describe('PC Mode', () => { expect(values).toEqual(Array.from({ length: 4 }, () => '')) }) - // slots test('default slot', async () => { const wrapper = mount(() => (