diff options
| author | Arnaud Bailly <arnaud@pankzsoft.com> | 2026-09-02 22:27:04 +0200 |
|---|---|---|
| committer | Arnaud Bailly <arnaud@pankzsoft.com> | 2026-09-02 22:27:04 +0200 |
| commit | d68fdea59aaf05877438bfba669c96d716523765 (patch) | |
| tree | 17913de3ed05cbc494b44b4ffabece46608c89f0 /pbt/ts/src/gen.ts | |
| parent | 7f69074b259f479b05777ba915a6ef3481a749af (diff) | |
| download | lambda-nantes-main.tar.gz | |
Diffstat (limited to 'pbt/ts/src/gen.ts')
| -rw-r--r-- | pbt/ts/src/gen.ts | 114 |
1 files changed, 95 insertions, 19 deletions
diff --git a/pbt/ts/src/gen.ts b/pbt/ts/src/gen.ts index 7d8c6f1..587bca6 100644 --- a/pbt/ts/src/gen.ts +++ b/pbt/ts/src/gen.ts @@ -5,7 +5,20 @@ import Prando from 'prando'; // namely the sequence of generated values in order to be // able to backtrack and shrink. -type GenMode = 'gen' | 'shrink'; +export interface Generators { + + genInt(): Gen<number>; + + genIntWithin(min: number, max: number): Gen<number>; + + genBytes(): GenBytes; + + genString(): Gen<string>; + + genList<A>(generator: Gen<A>): Gen<A[]>; + + replay(): void; +} export interface Gen<A> { generate(): A; @@ -13,11 +26,12 @@ export interface Gen<A> { generateN(n: number): A[]; } -export interface GenBytes { +interface GenBytes { + reject(): void; generate(n: number): number[]; } -export class BytesGen implements GenBytes { +class BytesGen implements GenBytes { prng: Prando; bytes: number[][]; // the internal sequence of generated values @@ -54,7 +68,7 @@ export class BytesGen implements GenBytes { } } -export class ReplayBytes implements GenBytes { +class ReplayBytes implements GenBytes { bytes: number[][]; // the internal sequence of generated values index: number = 0; // the current index in the sequence of generated values @@ -77,13 +91,18 @@ export class ReplayBytes implements GenBytes { return chunk; } + + reject() { + if (this.index >= this.bytes.length) { + throw new Error('No more bytes to shrink'); + } + this.index++; + } } class GenInt implements Gen<number> { - private bytes: BytesGen; - - constructor(seed: number | undefined = undefined) { - this.bytes = new BytesGen(new Prando(seed ? seed : Math.random() * 1000)); + constructor(private bytes: GenBytes) { + this.bytes = bytes; } generate(): number { @@ -102,10 +121,8 @@ class GenInt implements Gen<number> { } class GenIntWithin implements Gen<number> { - private bytes: BytesGen; - - constructor(private min: number, private max: number, seed: number | undefined = undefined) { - this.bytes = new BytesGen(new Prando(seed ? seed : Math.random() * 1000000000)); + constructor(private bytes: GenBytes, private min: number, private max: number) { + this.bytes = bytes; this.min = min; this.max = max; } @@ -148,10 +165,8 @@ class GenIntWithin implements Gen<number> { } class GenASCIIString implements Gen<string> { - private bytes: BytesGen; - - constructor(seed: number | undefined = undefined) { - this.bytes = new BytesGen(new Prando(seed ? seed : Math.random() * 1000)); + constructor(private bytes: GenBytes) { + this.bytes = bytes } generate(): string { @@ -169,8 +184,69 @@ class GenASCIIString implements Gen<string> { } } -export const genInt = (seed: number | undefined = undefined) => new GenInt(seed); +class Seeded implements Generators { + + constructor(private bytes: BytesGen) { + this.bytes = bytes; + } + + replay(): Generators { + return new Replayed(this.bytes); + } + + genInt(): Gen<number> { + return new GenInt(this.bytes); + } + genIntWithin(min: number, max: number): Gen<number> { + return new GenIntWithin(this.bytes, min, max); + } + genBytes(): GenBytes { + return this.bytes; + } + genString(): Gen<string> { + return new GenASCIIString(this.bytes); + } + genList<A>(generator: Gen<A>): Gen<A[]> { + throw new Error('Method not implemented.'); + } + +} + +class Replayed implements Generators { + bytes : GenBytes; + + constructor (bytes: BytesGen) { + this.bytes = bytes.replay(); + } + + replay(): Generators { + throw new Error('Cannot replay a replayed generator'); + } + + genInt(): Gen<number> { + return new GenInt(this.bytes); + } + genIntWithin(min: number, max: number): Gen<number> { + return new GenIntWithin(this.bytes, min, max); + } + genBytes(): GenBytes { + return this.bytes; + } + genString(): Gen<string> { + return new GenASCIIString(this.bytes); + } + genList<A>(generator: Gen<A>): Gen<A[]> { + throw new Error('Method not implemented.'); + } + +} + + +const generators = (seed: number | undefined = undefined) => { + const prng = new Prando(seed ? seed : Math.random() * 10000000); + const bytes = new BytesGen(prng); -export const genIntWithin = (min: number, max: number, seed: number | undefined = undefined) => new GenIntWithin(min, max, seed); + return new Seeded(bytes); +}; -export const genASCIIString = (seed: number | undefined = undefined) => new GenASCIIString(seed); +export default generators; |
