/* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable no-constant-binary-expression */
import { test } from "uvu";
import * as assert from "uvu/assert";

// eslint-disable-next-line @import/extensions
import clsx from "./clsx.ts";

// Change global defs for these tests.
// filterJoin is defined in foundry, polyfill here
Array.prototype.filterJoin = function (sep) {
    return this.filter((p) => !!p).join(sep);
};

// eslint-disable-next-line @typescript-eslint/no-empty-function
console.warn = () => {};

test("exports", () => {
    assert.type(clsx, "function", "exports default function");
    assert.type(clsx(), "string", "~> returns string output");
});

test("strings", () => {
    assert.is(clsx(""), "");
    assert.is(clsx("foo"), "foo");
    assert.is(clsx(true && "foo"), "foo");
    assert.is(clsx(false && "foo"), "");
});

test("strings (variadic)", () => {
    assert.is(clsx(""), "");
    assert.is(clsx("foo", "bar"), "foo bar");
    assert.is(clsx(true && "foo", false && "bar", "baz"), "foo baz");
    assert.is(clsx(false && "foo", "bar", "baz", ""), "bar baz");
});

test("numbers", () => {
    assert.is(clsx(1), "1");
    assert.is(clsx(12), "12");
    assert.is(clsx(0.1), "0.1");
    assert.is(clsx(0), "");

    assert.is(clsx(Infinity), "Infinity");
    assert.is(clsx(NaN), "");
});

test("numbers (variadic)", () => {
    assert.is(clsx(0, 1), "1");
    assert.is(clsx(1, 2), "1 2");
});

test("objects", () => {
    assert.is(clsx({}), "");
    assert.is(clsx({ foo: true }), "foo");
    assert.is(clsx({ foo: true, bar: false }), "foo");
    assert.is(clsx({ foo: true, bar: true }), "foo bar");
    assert.is(clsx({ foo: true, bar: false, baz: true }), "foo baz");
    assert.is(clsx({ "-foo": true, "--bar": true }), "-foo --bar");
});

test("objects (variadic)", () => {
    assert.is(clsx({}, {}), "");
    assert.is(clsx({ foo: true }, { bar: true }), "foo bar");
    assert.is(clsx({ foo: true }, null, { baz: true, bat: false }), "foo baz");
    assert.is(clsx({ foo: true }, {}, {}, { bar: true }, { baz: false, bat: true }), "foo bar bat");
});

test("arrays", () => {
    assert.is(clsx([]), "");
    assert.is(clsx(["foo"]), "foo");
    assert.is(clsx(["foo", "bar"]), "foo bar");
});

test("arrays (no `push` escape)", () => {
    assert.is(clsx({ push: true }), "push");
    assert.is(clsx({ pop: true }), "pop");
    assert.is(clsx({ push: true }), "push");
    assert.is(clsx("hello", { world: true, push: true }), "hello world push");
});

test.run();
