You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
58 lines
2.3 KiB
58 lines
2.3 KiB
export enum AssertionMode {
|
|
SKIP = "SKIP",
|
|
LOG = "LOG",
|
|
THROW = "THROW",
|
|
}
|
|
|
|
/** Configurations for the different assertion modes. */
|
|
export namespace AssertionConfig {
|
|
/** The types of the assertion configurations. */
|
|
export type Type = typeof Skip|typeof Throw|ReturnType<typeof Log>
|
|
/** An assertion configuration suitable for production, that skips assertions without evaluating them. */
|
|
export const Skip = {mode: AssertionMode.SKIP} as const
|
|
/** An assertion configuration suitable for testing, that throws an exception when an assertion fails. */
|
|
export const Throw = {mode: AssertionMode.THROW} as const
|
|
/** An assertion configuration suitable for debugging, that logs an exception when an assertion fails but allows the program to continue. */
|
|
export function Log(logger: (message?: any, ...params: any[]) => void) {
|
|
return {mode: AssertionMode.LOG, logger} as const
|
|
}
|
|
}
|
|
|
|
/** Assertion class for test-only checks on preconditions and postconditions. */
|
|
export class Assertions {
|
|
config: AssertionConfig.Type = AssertionConfig.Skip
|
|
|
|
/** General assert method. Checks that the condition is true. */
|
|
check<T>(value: T, condition: (value: T) => boolean, message: (value: T) => string): T {
|
|
if (this.config.mode === AssertionMode.SKIP) {
|
|
return value
|
|
}
|
|
const result = condition(value)
|
|
if (result) {
|
|
return value
|
|
}
|
|
const err = Error(message(value))
|
|
if (this.config.mode === AssertionMode.THROW) {
|
|
throw err
|
|
} else {
|
|
// All we can do is stand by and watch in horror...
|
|
this.config.logger(err)
|
|
return value
|
|
}
|
|
}
|
|
|
|
/** Checks that the value is an integer. */
|
|
checkInteger(value: number, message: (value: number) => string): number {
|
|
return this.check(value, Number.isSafeInteger, message)
|
|
}
|
|
|
|
/** Checks that the value is an integer and either positive or zero. */
|
|
checkPositiveIntegerOrZero(value: number, message: (value: number) => string): number {
|
|
return this.check(value, (value) => {
|
|
return Number.isSafeInteger(value) && value >= 0
|
|
}, message)
|
|
}
|
|
}
|
|
|
|
/** Global assertion object for use by other modules. */
|
|
export const assertion = new Assertions(); |