import { expect, test } from "vitest";
import merge from "./merge";

test("mergeValueAndOverride for booleans", () => {
  expect(merge<boolean>(true, undefined)).toBe(true);
  expect(merge<boolean>(true, false)).toBe(false);
  expect(merge<boolean>(false, true)).toBe(true);
});

test("mergeValueAndOverride for numbers", () => {
  expect(merge<number>(10, undefined)).toBe(10);
  expect(merge<number>(10, 0)).toBe(0);
  expect(merge<number>(10, 12)).toBe(12);
});

test("mergeValueAndOverride for strings", () => {
  expect(merge<string>("test", undefined)).toBe("test");
  expect(merge<string>("test", "")).toBe("");
  expect(merge<string>("test", "test-2")).toBe("test-2");
});

test("mergeValueAndOverride for lists", () => {
  expect(merge([123, 456], undefined)).toEqual([123, 456]);

  // Making list shorter
  expect(merge([123, 456], [])).toEqual([]);
  expect(merge([123, 456], [789])).toEqual([789]);

  // Overriding individual values
  expect(merge([123, 456], [undefined, 789])).toEqual([123, 789]);
  expect(merge([123, 456], [789, undefined])).toEqual([789, 456]);

  // Making list longer
  expect(merge([123, 456], [undefined, undefined, 789])).toEqual([
    123, 456, 789,
  ]);
  expect(merge([123, 456], [undefined, undefined, 789, undefined])).toEqual([
    123, 456, 789,
  ]);
  expect(
    merge([123, 456], [undefined, undefined, undefined, 789, undefined])
  ).toEqual([123, 456, 789]);
  expect(merge([123, 456], [1, 2, 3, 4])).toEqual([1, 2, 3, 4]);

  // Nested list
  expect(
    merge(
      [
        [1, 2],
        [3, 4],
      ],
      [undefined, [4, 5], [6], [7]]
    )
  ).toEqual([[1, 2], [4, 5], [6], [7]]);
});

test("mergeValueAndOverride for objects", () => {
  expect(merge({ a: 1, b: "str" }, undefined)).toEqual({
    a: 1,
    b: "str",
  });
  expect(merge({ a: 1, b: "str" }, {})).toEqual({
    a: 1,
    b: "str",
  });
  expect(merge({ a: 1, b: "str" }, { a: 2 })).toEqual({
    a: 2,
    b: "str",
  });
  expect(merge({ a: 1, b: "str" }, { b: "val" })).toEqual({
    a: 1,
    b: "val",
  });
  expect(
    merge<{ a: number; b: string; c?: string }>(
      { a: 1, b: "str" },
      { c: "val" }
    )
  ).toEqual({ a: 1, b: "str", c: "val" });
});
