import StringLengthConstraint from "../StringLengthConstraint";

describe("stringLengthConstraint", () => {
  it("min Length", () => {
    const constraint = new StringLengthConstraint(5);

    expect(constraint).toBeInstanceOf(StringLengthConstraint);
    expect(constraint.hasValidation()).toBe(true);
    expect(constraint.id).toBe("Constraint.InvalidLengthTooShort");
    expect(constraint.validate("abcd")).toBeFalsy();
    expect(constraint.validate("abcde")).toBeTruthy();
    expect(constraint.validate("abcdef")).toBeTruthy();
    expect(constraint.defaultMessage).toBe(
      "The length of the value  must be larger than ${min-length}",
    );
    expect(constraint.parameters).toStrictEqual({ "min-length": 5 });

    expect(() => {
      constraint.isLongEnough(123);
    }).toThrow(TypeError);

    expect(() => {
      new StringLengthConstraint(null, null).isLongEnough("test");
    }).toThrow(Error);

    expect(constraint.isMandatoryConstraint).toBe(false);
  });

  it("max Length", () => {
    const constraint = new StringLengthConstraint(null, 5);

    expect(constraint).toBeInstanceOf(StringLengthConstraint);
    expect(constraint.hasValidation()).toBe(true);
    expect(constraint.id).toBe("Constraint.InvalidLengthTooLong");
    expect(constraint.validate("abcd")).toBeTruthy();
    expect(constraint.validate("abcde")).toBeTruthy();
    expect(constraint.validate("abcdef")).toBeFalsy();
    expect(constraint.defaultMessage).toBe(
      "The length of the value must be smaller than ${max-length}",
    );
    expect(constraint.parameters).toStrictEqual({ "max-length": 5 });

    expect(() => {
      constraint.isSmallEnough(123);
    }).toThrow(TypeError);

    expect(() => {
      new StringLengthConstraint(null, null).isSmallEnough("test");
    }).toThrow(Error);
  });

  it("exact Length", () => {
    const constraint = new StringLengthConstraint(5, 5);

    expect(constraint).toBeInstanceOf(StringLengthConstraint);
    expect(constraint.hasValidation()).toBe(true);
    expect(constraint.id).toBe("Constraint.InvalidLengthExact");
    expect(constraint.validate("abcd")).toBeFalsy();
    expect(constraint.validate("abcde")).toBeTruthy();
    expect(constraint.validate("abcdef")).toBeFalsy();
    expect(constraint.defaultMessage).toBe(
      "Length must be precisely ${length} characters",
    );
    expect(constraint.parameters).toStrictEqual({
      length: 5,
    });

    expect(() => {
      constraint.isExactLength(123);
    }).toThrow(TypeError);

    expect(() => {
      new StringLengthConstraint(null, null).isExactLength("test");
    }).toThrow(Error);
  });

  it("between Length", () => {
    const constraint = new StringLengthConstraint(4, 6);

    expect(constraint).toBeInstanceOf(StringLengthConstraint);
    expect(constraint.hasValidation()).toBe(true);
    expect(constraint.id).toBe("Constraint.InvalidLengthBetween");
    expect(constraint.validate("abc")).toBeFalsy();
    expect(constraint.validate("abcde")).toBeTruthy();
    expect(constraint.validate("abcdefg")).toBeFalsy();
    expect(constraint.defaultMessage).toBe(
      "Length must be between ${min-length} and ${max-length} characters",
    );
    expect(constraint.parameters).toStrictEqual({
      "min-length": 4,
      "max-length": 6,
    });

    expect(() => {
      constraint.isBetween(123);
    }).toThrow(TypeError);

    expect(() => {
      new StringLengthConstraint(null, null).isBetween("test");
    }).toThrow(Error);
  });
});
