import "./functions/geninq";
import "./functions/async";

export function It<T, TEle = number>(
  name: string,
  test: (gen: Generator<TEle>) => T,
  expected: T,
  start?: TEle[]
) {
  it(name + " async", async () =>
    expect(await test((start ?? [1, 2, 3]).geninq().async() as any)).toEqual(
      expected
    )
  );
  it(name + " sync", async () =>
    expect(test((start ?? [1, 2, 3]).geninq() as any)).toEqual(expected)
  );
}

export function ItThrows<T, TEle = number>(
  name: string,
  test: (gen: Generator<TEle>) => T,
  expected: Error,
  start?: TEle[]
) {
  it(name + " async", async () => {
    try {
      await test((start ?? [1, 2, 3]).geninq().async() as any);
    } catch (err) {
      expect(err).toEqual(expected);
      return;
    }

    throw new Error("Test did not throw");
  });
  it(name + " sync", async () =>
    expect(() => test((start ?? [1, 2, 3]).geninq() as any)).toThrow(expected)
  );
}

export function AIt<T, TEle = number>(
  name: string,
  test: (gen: AsyncGenerator<TEle>) => Promise<T> | T,
  expected: T,
  start?: TEle[]
) {
  it(name + " async", async () =>
    expect(await test((start ?? [1, 2, 3]).geninq().async() as any)).toEqual(
      expected
    )
  );
}

export function SIt<T, TEle = number>(
  name: string,
  test: (gen: Generator<TEle>) => T,
  expected: T,
  start?: TEle[]
) {
  it(name + " sync", async () =>
    expect(test((start ?? [1, 2, 3]).geninq() as any)).toEqual(expected)
  );
}
