// Función genérica para asegurar valores básicos
function ensure<T>(value: T | undefined | null, defaultValue: T): T {
  return value ?? defaultValue;
}

// Implementaciones específicas para tipos básicos
const ensureString = (value?: string): string => ensure(value, "");
const ensureNumber = (value?: number): number => ensure(value, 0);
const ensureBoolean = (value?: boolean): boolean => ensure(value, false);
const ensureBigInt = (value?: bigint): bigint => ensure(value, BigInt(0));
const ensureSymbol = (value?: symbol, defaultSymbol = Symbol()): symbol =>
  ensure(value, defaultSymbol);

describe("ensure functions", () => {
  test("ensureString should return string value or default", () => {
    expect(ensureString("Hola")).toBe("Hola");
    expect(ensureString(undefined)).toBe("");
    expect(ensureString(null as any)).toBe("");
  });

  test("ensureNumber should return number value or default", () => {
    expect(ensureNumber(42)).toBe(42);
    expect(ensureNumber(undefined)).toBe(0);
    expect(ensureNumber(null as any)).toBe(0);
  });

  test("ensureBoolean should return boolean value or default", () => {
    expect(ensureBoolean(true)).toBe(true);
    expect(ensureBoolean(false)).toBe(false);
    expect(ensureBoolean(undefined)).toBe(false);
    expect(ensureBoolean(null as any)).toBe(false);
  });

  test("ensureBigInt should return bigint value or default", () => {
    expect(ensureBigInt(BigInt(123))).toBe(BigInt(123));
    expect(ensureBigInt(undefined)).toBe(BigInt(0));
    expect(ensureBigInt(null as any)).toBe(BigInt(0));
  });

  test("ensureSymbol should return symbol value or default", () => {
    const sym = Symbol("test");
    expect(ensureSymbol(sym)).toBe(sym);
    expect(typeof ensureSymbol(undefined)).toBe("symbol");
    expect(typeof ensureSymbol(null as any)).toBe("symbol");
  });
});
