Skip to content

Instantly share code, notes, and snippets.

type Generator<T> = {
generate(mrng: Random): T;
}
class Random {
constructor(rng) {
this.rng = rng;
}
next(min, max) {
const g = prand.uniformIntDistribution(min, max, this.rng);
this.rng = g[1];
return g[0];
}
}
// const miniFc = {}
miniFc.integer = (min, max) => {
return {
generate(mrng) {
return mrng.next(min, max);
}
};
}
// It can be used as follow:
declare function map<T, U>(g: Generator<T>, mapper: (v: T) => U): Generator<U>;
function map(g, mapper) {
return {
generate(mrng) {
const value = g.generate(mrng);
return mapper(value);
}
};
}
miniFc.boolean = () => map(
miniFc.integer(0, 1),
Boolean
)
miniFc.character = () => map(
miniFc.integer(0, 25),
n => String.fromCharCode(97 + n)
)
miniFc.tuple = (...itemGenerators) => {
return {
generate(mrng) {
return itemGenerators.map(g => g.generate(mrng));
}
};
}
// It can be used as follow:
// > miniFc.tuple(miniFc.integer(0, 50), miniFc.boolean()).generate(mrng)
miniFc.string = () => map(
miniFc.array(miniFc.character()),
characters => characters.join('')
)
miniFc.dictionary = (valueGenerator) => map(
miniFc.array(
miniFc.tuple(
miniFc.string(),
valueGenerator
type Property<T> = {
generate(mrng: Random): T;
run(valueUnderTest: T): boolean;
}
miniFc.property = (generator, predicate) => {
return {
generate(mrng) {
return generator.generate(mrng);
},
run(valueUnderTest) {
return predicate(valueUnderTest);
}
}
}