import { describe, expect, it } from "vitest";
import { format, defineConfig } from "../../dist/index.js";
import type { FormatConfig } from "../../dist/index.js";

describe("defineConfig() API", () => {
  it("`defineConfig()` function exists", () => {
    expect(typeof defineConfig).toBe("function");
  });

  it("`defineConfig()` returns the same object", () => {
    const config = defineConfig({ semi: true, tabWidth: 4, ignorePatterns: ["*.min.js"] });
    expect(config).toStrictEqual({ semi: true, tabWidth: 4, ignorePatterns: ["*.min.js"] });
  });
});

describe("format() API", () => {
  it("`format()` function exists", () => {
    expect(typeof format).toBe("function");
  });

  it("dynamic import also works", async () => {
    const { format } = await import("../../dist/index.js");
    const result = await format("a.ts", "const x:number=42");
    expect(result.code).toBe("const x: number = 42;\n");
    expect(result.errors).toStrictEqual([]);
  });

  it("should `format()` multiple times w/o panic", async () => {
    const result1 = await format("a.ts", "const x:number=42");
    expect(result1.code).toBe("const x: number = 42;\n");
    expect(result1.errors).toStrictEqual([]);

    const result2 = await format("a.json", '{"key":           "value"}');
    expect(result2.code).toBe('{ "key": "value" }\n');
    expect(result2.errors).toStrictEqual([]);
  });

  it("should TS types and options work", async () => {
    const options: FormatConfig = {
      quoteProps: "as-needed", // Can be string literal
      printWidth: 120,
      semi: false,
      experimentalSortPackageJson: false,
      experimentalSortImports: {
        // Can be optional object
        partitionByComment: false,
      },
    };

    const result = await format("a.ts", "const x={'y':1}", options);
    expect(result.code).toBe("const x = { y: 1 }\n");
    expect(result.errors).toStrictEqual([]);

    const { errors } = await format("a.ts", "const x={'y':1}", {
      // @ts-expect-error: Test invalid options is validated
      semi: "invalid",
    });
    expect(errors.length).toBe(1);
  });
});
