covertable
Version:
Efficient TypeScript library for pairwise testing, generating minimal covering arrays with constraint support.
164 lines (151 loc) • 5.37 kB
TypeScript
/**
* Arithmetic expressions compute a value from two operands.
* Both `left` and `right` can be field references or nested expressions.
* When `right` is omitted, `value` provides a literal operand.
*/
declare type ArithmeticExpression = {
operator: 'add' | 'sub' | 'mul' | 'div' | 'mod' | 'pow';
left: Operand;
right: Operand;
} | {
operator: 'add' | 'sub' | 'mul' | 'div' | 'mod' | 'pow';
left: Operand;
value: any;
};
declare type ArrayObjectType = {
[s: string]: any[];
};
/**
* A comparison condition. `left` is the first operand (field reference or
* expression). The second operand is either `right` (another field/expression)
* or `value` (a literal). For `in`, use `values` (an array of literals).
*/
declare type ComparisonExpression = {
operator: 'eq';
left: Operand;
value: any;
} | {
operator: 'eq';
left: Operand;
right: Operand;
} | {
operator: 'ne';
left: Operand;
value: any;
} | {
operator: 'ne';
left: Operand;
right: Operand;
} | {
operator: 'gt';
left: Operand;
value: any;
} | {
operator: 'gt';
left: Operand;
right: Operand;
} | {
operator: 'lt';
left: Operand;
value: any;
} | {
operator: 'lt';
left: Operand;
right: Operand;
} | {
operator: 'gte';
left: Operand;
value: any;
} | {
operator: 'gte';
left: Operand;
right: Operand;
} | {
operator: 'lte';
left: Operand;
value: any;
} | {
operator: 'lte';
left: Operand;
right: Operand;
} | {
operator: 'in';
left: Operand;
values: any[];
};
/**
* Constraint builder with `$`-prefixed field references and type-safe
* autocompletion via template literal types.
*
* ```typescript
* const c = new Constraint<typeof factors>();
* c.eq("$OS", "Mac")
* c.gt(c.mul("$Price", "$Qty"), 10000)
* c.sum("$A", "$B", "$C")
* ```
*/
export declare class Constraint<T extends Record<string, readonly any[]> = ArrayObjectType> {
eq(left: FieldOrExpr<T>, right: FieldOrExpr<T> | RightOperand<T>): Expression;
ne(left: FieldOrExpr<T>, right: FieldOrExpr<T> | RightOperand<T>): Expression;
gt(left: FieldOrExpr<T>, right: FieldOrExpr<T> | RightOperand<T>): Expression;
lt(left: FieldOrExpr<T>, right: FieldOrExpr<T> | RightOperand<T>): Expression;
gte(left: FieldOrExpr<T>, right: FieldOrExpr<T> | RightOperand<T>): Expression;
lte(left: FieldOrExpr<T>, right: FieldOrExpr<T> | RightOperand<T>): Expression;
in(left: FieldOrExpr<T>, values: any[]): Expression;
and(...conditions: Expression[]): Expression;
or(...conditions: Expression[]): Expression;
not(condition: Expression): Expression;
add(left: FieldOrExpr<T> | RightOperand<T>, right: FieldOrExpr<T> | RightOperand<T>): ArithmeticExpression;
sub(left: FieldOrExpr<T> | RightOperand<T>, right: FieldOrExpr<T> | RightOperand<T>): ArithmeticExpression;
mul(left: FieldOrExpr<T> | RightOperand<T>, right: FieldOrExpr<T> | RightOperand<T>): ArithmeticExpression;
div(left: FieldOrExpr<T> | RightOperand<T>, right: FieldOrExpr<T> | RightOperand<T>): ArithmeticExpression;
mod(left: FieldOrExpr<T> | RightOperand<T>, right: FieldOrExpr<T> | RightOperand<T>): ArithmeticExpression;
pow(left: FieldOrExpr<T> | RightOperand<T>, right: FieldOrExpr<T> | RightOperand<T>): ArithmeticExpression;
sum(...args: (FieldOrExpr<T> | RightOperand<T>)[]): ArithmeticExpression;
product(...args: (FieldOrExpr<T> | RightOperand<T>)[]): ArithmeticExpression;
fn(requires: (string & keyof T)[], evaluate: (row: {
[K in keyof T]: any;
}) => boolean): Expression;
val(value: any): ValWrapper;
}
declare type Expression = ComparisonExpression | LogicalExpression | FnExpression;
/** A field reference or arithmetic expression (resolves to an Operand). */
declare type FieldOrExpr<T> = `$${string & keyof T}` | ArithmeticExpression;
/**
* Escape hatch for constraints that cannot be expressed declaratively.
* The engine cannot perform three-valued reasoning on these — when a
* dependency key is missing the condition is treated as `null`.
* Provide `requires` so the engine knows when it is safe to call `evaluate`.
*/
declare type FnExpression = {
operator: 'fn';
requires: string[];
evaluate: (row: {
[key: string]: any;
}) => boolean;
};
/** A literal value (preserves template literal autocomplete via `string & {}`). */
declare type Literal = (string & {}) | number | boolean | null;
declare type LogicalExpression = {
operator: 'not';
condition: Expression;
} | {
operator: 'and';
conditions: Expression[];
} | {
operator: 'or';
conditions: Expression[];
};
/**
* An operand is either a field reference (string, supports dot notation
* like `"payment.method"`) or an arithmetic expression.
*/
declare type Operand = string | ArithmeticExpression;
/** Right-hand operand: field reference, expression, literal, or val-wrapped. */
declare type RightOperand<T> = FieldOrExpr<T> | Literal | ValWrapper;
/** Wrapper to force a value to be treated as a literal, not a field reference. */
declare type ValWrapper = {
__val: true;
value: any;
};
export { }