Property Test Generator With Shrinking

Generate random inputs for a property test and shrink a failing case to a minimal counterexample.

TypescriptData Integrity

Code

snippet
export interface PropertyCase { readonly numbers: number[]; }

export function check(numbers: number[]): boolean {
  return numbers.every((n, i) => i === 0 || (numbers[i - 1] as number) <= n);
}

export function shrink(failing: number[], holds: (input: number[]) => boolean): number[] {
  let current = failing;
  let changed = true;
  while (changed) {
    changed = false;
    for (let i = 0; i < current.length; i++) {
      const candidate = current.filter((_, index) => index !== i);
      if (!holds(candidate)) {
        current = candidate;
        changed = true;
        break;
      }
    }
  }
  return current;
}

export function findCounterexample(seed: number[], holds: (input: number[]) => boolean): number[] | null {
  if (!holds(seed)) return shrink(seed, holds);
  return null;
}