import { ValueObject } from "./value-object";

interface TestValueProps {
  value: string;
}

class TestValueObject extends ValueObject<TestValueProps> {
  constructor(value: string) {
    super({ value });
  }

  getValue() {
    return this.props;
  }
}

describe("ValueObject", () => {
  test("debe considerar dos ValueObjects con los mismos valores como iguales", () => {
    const vo1 = new TestValueObject("test");
    const vo2 = new TestValueObject("test");
    expect(vo1.equals(vo2)).toBe(true);
  });

  test("debe considerar dos ValueObjects con valores diferentes como distintos", () => {
    const vo1 = new TestValueObject("test1");
    const vo2 = new TestValueObject("test2");
    expect(vo1.equals(vo2)).toBe(false);
  });

  test("debe devolver false si el objeto comparado no es una instancia de ValueObject", () => {
    const vo1 = new TestValueObject("test");
    expect(vo1.equals({ prop: "test" } as any)).toBe(false);
  });

  test("debe devolver false si el objeto comparado es null o undefined", () => {
    const vo1 = new TestValueObject("test");
    expect(vo1.equals(null as any)).toBe(false);
    expect(vo1.equals(undefined as any)).toBe(false);
  });

  test("debe garantizar la inmutabilidad de las propiedades", () => {
    const vo = new TestValueObject("immutable");
    expect(() => {
      (vo as any).props.prop = "mutated";
    }).toThrow();
  });
});
