import { describe, it, expect } from 'vitest';
import { z } from '@hono/zod-openapi';
import { parseWithAwait } from '../../src/utils/parseWithAwait';

describe('parseWithAwait', () => {
  const testSchema = z.object({
    name: z.string(),
    age: z.number(),
    email: z.string().email()
  });

  it('应该成功解析同步数据', async () => {
    const data = {
      name: 'John Doe',
      age: 30,
      email: 'john@example.com'
    };

    const result = await parseWithAwait(testSchema, data);

    expect(result).toEqual(data);
  });

  it('应该成功解析包含Promise的数据', async () => {
    const data = {
      name: Promise.resolve('John Doe'),
      age: 30,
      email: 'john@example.com'
    };

    const result = await parseWithAwait(testSchema, data);

    expect(result).toEqual({
      name: 'John Doe',
      age: 30,
      email: 'john@example.com'
    });
  });

  it('应该处理嵌套对象中的Promise', async () => {
    const nestedSchema = z.object({
      user: z.object({
        name: z.string(),
        profile: z.object({
          age: z.number()
        })
      })
    });

    const data = {
      user: {
        name: Promise.resolve('John Doe'),
        profile: {
          age: Promise.resolve(30)
        }
      }
    };

    const result = await parseWithAwait(nestedSchema, data);

    expect(result).toEqual({
      user: {
        name: 'John Doe',
        profile: {
          age: 30
        }
      }
    });
  });

  it('当数据不符合schema时应该抛出错误', async () => {
    const invalidData = {
      name: 'John Doe',
      age: 'not-a-number', // 应该是数字
      email: 'john@example.com'
    };

    await expect(parseWithAwait(testSchema, invalidData))
      .rejects
      .toThrow();
  });

  it('应该处理数组中的Promise', async () => {
    const arraySchema = z.object({
      items: z.array(z.object({
        name: z.string(),
        value: z.number()
      }))
    });

    const data = {
      items: [
        { name: Promise.resolve('Item 1'), value: 10 },
        { name: 'Item 2', value: Promise.resolve(20) }
      ]
    };

    const result = await parseWithAwait(arraySchema, data);

    expect(result).toEqual({
      items: [
        { name: 'Item 1', value: 10 },
        { name: 'Item 2', value: 20 }
      ]
    });
  });
});