Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// eslint-disable-next-line @ts/no-explicit-any
type ErrorConstructorType = new (...args: any) => Error;

export type { ErrorConstructorType };
6 changes: 2 additions & 4 deletions packages/testing-ground/src/utils/compare-errors.mts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { isValidationError } from "./is-validation-error.mjs";
import { validateError } from "./validate-error.mjs";
import { wrapCause } from "./wrap-cause.mjs";

function compareErrors(value: unknown, expected: Error): void
{
// @ts-expect-error -- constructor is badly typed
const CONSTRUCTOR_CLASS: typeof Error = expected.constructor;

if (!(value instanceof CONSTRUCTOR_CLASS))
{
throw new Error(`An ${CONSTRUCTOR_CLASS.name} must be thrown.`);
}
validateError(value, CONSTRUCTOR_CLASS);

if (value.message !== expected.message)
{
Expand Down
44 changes: 24 additions & 20 deletions packages/testing-ground/src/utils/create-error-test.mts
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
import type { ErrorConstructorType } from "../definition/type/error-constructor.type.mjs";
import { compareErrors } from "./compare-errors.mjs";
import { validateError } from "./validate-error.mjs";

function createErrorTest(expected_error?: Error | RegExp | string): (value: unknown) => true
function createErrorTest(expected_error?: Error | ErrorConstructorType | RegExp | string): (value: unknown) => true
{
return (value: unknown): true =>
{
if (expected_error === undefined || expected_error instanceof RegExp)
{
if (!(value instanceof Error))
{
throw new Error("An Error must be thrown.");
}

if (value.message.length === 0)
{
throw new Error("An error must have a message.");
}

if (expected_error instanceof RegExp && !expected_error.test(value.message))
{
throw new Error(`Expected error message to match ${expected_error.toString()} but got "${value.message}"`);
}
}
else if (expected_error instanceof Error)
if (expected_error instanceof Error)
{
compareErrors(value, expected_error);

return true;
}
else

if (typeof expected_error === "string")
{
compareErrors(value, new Error(expected_error));

return true;
}

if (typeof expected_error === "function")
{
validateError(value, expected_error);

return true;
}

validateError(value, Error);

if (expected_error instanceof RegExp && !expected_error.test(value.message))
{
throw new Error(`Expected error message to match ${expected_error.toString()} but got "${value.message}".`);
}

return true;
Expand Down
16 changes: 16 additions & 0 deletions packages/testing-ground/src/utils/validate-error.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { ErrorConstructorType } from "../definition/type/error-constructor.type.mjs";

function validateError(value: unknown, error_constructor: ErrorConstructorType): asserts value is Error
{
if (!(value instanceof error_constructor))
{
throw new Error(`An instance of ${error_constructor.name} must be thrown.`);
}

if (value.message.length === 0)
{
throw new Error("An error must have a message.");
}
}

export { validateError };
2 changes: 1 addition & 1 deletion packages/ts-predicate/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vitruvius-labs/ts-predicate",
"version": "7.2.0",
"version": "7.2.1",
"description": "TypeScript predicates library",
"author": {
"name": "VitruviusLabs"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { assertInteger } from "../../../type-assertion/assert-integer.mjs";
import { ValidationError } from "../../../type-assertion/utils/validation-error.mjs";

function assertBetween(value: unknown, min: number, max: number): void
{
assertInteger(value);

if (value < min || max < value)
{
throw new RangeError(`Value ${value.toFixed(0)} is not between ${min.toFixed(0)} and ${max.toFixed(0)}.`);
throw new ValidationError(`Value ${value.toFixed(0)} is not between ${min.toFixed(0)} and ${max.toFixed(0)}.`);
}
}

Expand Down
3 changes: 2 additions & 1 deletion packages/ts-predicate/src/type-assertion/assert-nullable.mts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { isNullable } from "../type-guard/is-nullable.mjs";
import { ValidationError } from "./utils/validation-error.mjs";

function assertNullable(value: unknown): asserts value is null | undefined
{
if (!isNullable(value))
{
throw new TypeError("Value must be null or undefined.");
throw new ValidationError("Value must be null or undefined.");
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { doesNotThrow, throws } from "node:assert";
import { describe, it } from "node:test";
import { GroupType, consumeValue, createErrorTest, createValue, getInvertedValues, getValues } from "@vitruvius-labs/testing-ground";
import { assertInt16 } from "../../../../../src/_index.mjs";
import { ValidationError, assertInt16 } from "../../../../../src/_index.mjs";
import { IntegerBoundaryEnum } from "../../../../../src/extended/integer/definition/enum/integer-boundary.enum.mjs";

describe("assertInt16", (): void => {
Expand Down Expand Up @@ -40,7 +40,7 @@ describe("assertInt16", (): void => {
assertInt16(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -54,7 +54,7 @@ describe("assertInt16", (): void => {
assertInt16(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -68,7 +68,7 @@ describe("assertInt16", (): void => {
assertInt16(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { doesNotThrow, throws } from "node:assert";
import { describe, it } from "node:test";
import { GroupType, consumeValue, createErrorTest, createValue, getInvertedValues, getValues } from "@vitruvius-labs/testing-ground";
import { assertInt32 } from "../../../../../src/_index.mjs";
import { ValidationError, assertInt32 } from "../../../../../src/_index.mjs";
import { IntegerBoundaryEnum } from "../../../../../src/extended/integer/definition/enum/integer-boundary.enum.mjs";

describe("assertInt32", (): void => {
Expand Down Expand Up @@ -40,7 +40,7 @@ describe("assertInt32", (): void => {
assertInt32(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -54,7 +54,7 @@ describe("assertInt32", (): void => {
assertInt32(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -68,7 +68,7 @@ describe("assertInt32", (): void => {
assertInt32(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { doesNotThrow, throws } from "node:assert";
import { describe, it } from "node:test";
import { GroupType, consumeValue, createErrorTest, createValue, getInvertedValues, getValues } from "@vitruvius-labs/testing-ground";
import { assertInt8 } from "../../../../../src/_index.mjs";
import { ValidationError, assertInt8 } from "../../../../../src/_index.mjs";
import { IntegerBoundaryEnum } from "../../../../../src/extended/integer/definition/enum/integer-boundary.enum.mjs";

describe("assertInt8", (): void => {
Expand Down Expand Up @@ -40,7 +40,7 @@ describe("assertInt8", (): void => {
assertInt8(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -54,7 +54,7 @@ describe("assertInt8", (): void => {
assertInt8(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -68,7 +68,7 @@ describe("assertInt8", (): void => {
assertInt8(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { doesNotThrow, throws } from "node:assert";
import { describe, it } from "node:test";
import { GroupType, consumeValue, createErrorTest, createValue, getInvertedValues, getValues } from "@vitruvius-labs/testing-ground";
import { assertUInt16 } from "../../../../../src/_index.mjs";
import { ValidationError, assertUInt16 } from "../../../../../src/_index.mjs";
import { IntegerBoundaryEnum } from "../../../../../src/extended/integer/definition/enum/integer-boundary.enum.mjs";

describe("assertUInt16", (): void => {
Expand Down Expand Up @@ -34,7 +34,7 @@ describe("assertUInt16", (): void => {
assertUInt16(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -48,7 +48,7 @@ describe("assertUInt16", (): void => {
assertUInt16(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -62,7 +62,7 @@ describe("assertUInt16", (): void => {
assertUInt16(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { doesNotThrow, throws } from "node:assert";
import { describe, it } from "node:test";
import { GroupType, consumeValue, createErrorTest, createValue, getInvertedValues, getValues } from "@vitruvius-labs/testing-ground";
import { assertUInt32 } from "../../../../../src/_index.mjs";
import { ValidationError, assertUInt32 } from "../../../../../src/_index.mjs";
import { IntegerBoundaryEnum } from "../../../../../src/extended/integer/definition/enum/integer-boundary.enum.mjs";

describe("assertUInt32", (): void => {
Expand Down Expand Up @@ -34,7 +34,7 @@ describe("assertUInt32", (): void => {
assertUInt32(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -48,7 +48,7 @@ describe("assertUInt32", (): void => {
assertUInt32(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -62,7 +62,7 @@ describe("assertUInt32", (): void => {
assertUInt32(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { doesNotThrow, throws } from "node:assert";
import { describe, it } from "node:test";
import { GroupType, consumeValue, createErrorTest, createValue, getInvertedValues, getValues } from "@vitruvius-labs/testing-ground";
import { assertUInt8 } from "../../../../../src/_index.mjs";
import { ValidationError, assertUInt8 } from "../../../../../src/_index.mjs";
import { IntegerBoundaryEnum } from "../../../../../src/extended/integer/definition/enum/integer-boundary.enum.mjs";

describe("assertUInt8", (): void => {
Expand Down Expand Up @@ -34,7 +34,7 @@ describe("assertUInt8", (): void => {
assertUInt8(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -48,7 +48,7 @@ describe("assertUInt8", (): void => {
assertUInt8(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand All @@ -62,7 +62,7 @@ describe("assertUInt8", (): void => {
assertUInt8(ITEM);
};

throws(WRAPPER, createErrorTest());
throws(WRAPPER, createErrorTest(ValidationError));
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { doesNotThrow, throws } from "node:assert";
import { describe, it } from "node:test";
import { consumeValue, createErrorTest, createValue } from "@vitruvius-labs/testing-ground";
import { type Nullish, assertNullishProperty, assertString } from "../../../../../src/_index.mjs";
import { type Nullish, ValidationError, assertNullishProperty, assertString } from "../../../../../src/_index.mjs";

describe("assertNullishProperty", (): void => {
it("should throw when given an object without the property", (): void => {
Expand All @@ -15,8 +15,8 @@ describe("assertNullishProperty", (): void => {
assertNullishProperty({}, SYMBOL);
};

throws(WRAPPER_STRING, createErrorTest("The value must have a property \"key\"."));
throws(WRAPPER_SYMBOL, createErrorTest("The value must have a property \"Symbol(key)\"."));
throws(WRAPPER_STRING, createErrorTest(new ValidationError("The value must have a property \"key\".")));
throws(WRAPPER_SYMBOL, createErrorTest(new ValidationError("The value must have a property \"Symbol(key)\".")));
});

it("should return when given an object with the property", (): void => {
Expand All @@ -42,7 +42,7 @@ describe("assertNullishProperty", (): void => {
consumeValue<{ key: unknown }>(VALUE);
};

throws(WRAPPER, createErrorTest('The value must have a property "key".'));
throws(WRAPPER, createErrorTest(new ValidationError('The value must have a property "key".')));
});

it("should narrow the type to an object with the corresponding property (symbol)", (): void => {
Expand All @@ -55,7 +55,7 @@ describe("assertNullishProperty", (): void => {
consumeValue<{ [SYMBOL]: unknown }>(VALUE);
};

throws(WRAPPER, createErrorTest('The value must have a property "Symbol(key)".'));
throws(WRAPPER, createErrorTest(new ValidationError('The value must have a property "Symbol(key)".')));
});

it("should narrow the type to an object with the corresponding property (type)", (): void => {
Expand All @@ -68,6 +68,6 @@ describe("assertNullishProperty", (): void => {
consumeValue<Date & { [SYMBOL]: Nullish<string> }>(VALUE);
};

throws(WRAPPER, createErrorTest('The value must have a property "Symbol(key)".'));
throws(WRAPPER, createErrorTest(new ValidationError('The value must have a property "Symbol(key)".')));
});
});
Loading
Loading