Repository: element-plus/element-plus
File: packages/components/image/__tests__/image.test.tsx (TypeScript)

Code before:
async function doubleWait() {
  await nextTick()
  await nextTick()
}

async function waitUntil(
  condition: () => boolean,
  timeout = 3000,
  interval = 100
) {
  const startTime = Date.now()

  while (Date.now() - startTime < timeout) {
    if (condition()) return
    await nextTick()
    await flushPromises()

    if (condition()) return
    await new Promise((resolve) => setTimeout(resolve, interval))
  }

  if (!condition()) {
    throw new Error(`Condition not met within ${timeout}ms timeout`)
  }
}

const _mount = (template: string, data: Record<string, any>) =>
  mount({
    components: {
      [Image.name!]: Image,
    },
    template,
    data,
  })

describe('Image.vue', () => {
  test('render test', () => {
    const wrapper = mount(Image)
    expect(wrapper.find('.el-image').exists()).toBe(true)
  })

  test('imageStyle fit test', async () => {
    const fits = ['fill', 'contain', 'cover', 'none', 'scale-down'] as const
    for (const fit of fits) {
      const wrapper = mount(() => <Image src={IMAGE_SUCCESS} fit={fit} />)
      await doubleWait()
      expect(wrapper.find('img').attributes('style')).toContain(
        `object-fit: ${fit};`
      )
    }
  })

Review comment (suggestion):
```suggestion
function waitUntil(condition, timeout = 3000, interval = 100) {
  const start = Date.now()
  return new Promise(async (resolve, reject) => {
    async function check() {
      await nextTick()
      await flushPromises()
      if (condition()) return resolve()
      if (Date.now() - start >= timeout) return reject(`Condition not met within ${timeout}ms timeout`)
      setTimeout(check, interval)
    }
    check()
  })
}
```

Code after:
// secondly wait for vue render
async function doubleWait() {
  await nextTick()
  await nextTick()
}

const _mount = (template: string, data: Record<string, any>) =>
  mount({
    components: {
      [Image.name!]: Image,
    },
    template,
    data,
  })

describe('Image.vue', () => {
  test('render test', () => {
    const wrapper = mount(Image)
    expect(wrapper.find('.el-image').exists()).toBe(true)
  })

  test('imageStyle fit test', async () => {
    const fits = ['fill', 'contain', 'cover', 'none', 'scale-down'] as const
    for (const fit of fits) {
      const wrapper = mount(() => <Image src={IMAGE_SUCCESS} fit={fit} />)
      await doubleWait()
      expect(wrapper.find('img').attributes('style')).toContain(
        `object-fit: ${fit};`
      )
    }
  })

  test('preview classname test', async () => {
    const props: ElImageProps = {
      fit: 'cover',
      src: IMAGE_SUCCESS,
      previewSrcList: Array.from<string>({ length: 3 }).fill(IMAGE_SUCCESS),
    }
    const wrapper = mount(() => <Image {...props} />)
    await doubleWait()
    expect(wrapper.find('img').classes()).toContain('el-image__preview')
  })

  test('preview initial index test', async () => {
    const props: ElImageProps = {
      src: IMAGE_SUCCESS,
      previewSrcList: Array.from<string>({ length: 3 }).map(
        (_, idx) => IMAGE_FAIL + idx
      ),
      initialIndex: 1,
    }