Part 2: Runners

node v14.20.1
version: 2.0.0
endpointsharetweet
Let's define our minimal framework
const prand = require('pure-rand'); 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]; } } function map(g, mapper) { return { generate(mrng) { const value = g.generate(mrng); return mapper(value); } }; } const miniFc = {} miniFc.integer = (min, max) => { return { generate(mrng) { return mrng.next(min, max); } }; } 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)); } }; } miniFc.array = (itemGenerator) => { return { generate(mrng) { const size = mrng.next(0, 10); const content = []; for (let index = 0 ; index !== size ; ++index) { content.push(itemGenerator.generate(mrng)); } return content; } }; } miniFc.string = () => map( miniFc.array(miniFc.character()), characters => characters.join('') ) miniFc.dictionary = (valueGenerator) => map( miniFc.array( miniFc.tuple( miniFc.string(), valueGenerator ) ), Object.fromEntries ) miniFc.property = (generator, predicate) => { return { generate(mrng) { return generator.generate(mrng); }, run(valueUnderTest) { return predicate(valueUnderTest); } } } miniFc.assert = (property, { seed = Date.now() } = {}) => { let rng = prand.xoroshiro128plus(seed); for (let runId = 0 ; runId !== 100 ; ++runId) { const valueUnderTest = property.generate(new Random(rng)); if (!property.run(valueUnderTest)) { throw new Error(`Property failed after ${runId + 1} runs with value ${JSON.stringify(valueUnderTest)} (seed: ${seed})`); } rng = rng.jump(); } }
Let's use it!
const isSubstring = (pattern, text) => { return text.indexOf(pattern) > 0; } miniFc.assert( miniFc.property( miniFc.tuple(miniFc.string(), miniFc.string(), miniFc.string()), ([a, b, c]) => isSubstring(b, a + b + c) ) )
Loading…

no comments

    sign in to comment