Generator Combinators

Create new generators by combining existing generators

One of the powerful things about generators is that you can take the existing pre-built generators and combine them to create almost any possible data using the functions on this page. They are used heavily in the source of quick_check.js itself.

qc.oneOf(generators...)

Generates a value by choosing randomly one of the passed generators and generating a value from it.

var stringOrNumber = qc.oneOf(qc.string, qc.real);
stringOrNumber(size); //=> "frqw"
stringOrNumber(size); //=> 5.54
stringOrNumber = qc.oneOf(qc.string, qc.real)
stringOrNumber(size) # "frqw"
stringOrNumber(size) # 5.54
let stringOrNumber: QCGenerator<string|number> = qc.oneOf(qc.string, qc.real);
stringOrNumber(size); //=> "frqw"
stringOrNumber(size); //=> 5.54

qc.oneOfByPriority(generators...)

Works identically to qc.oneOf, but will choose earlier generators more often than later ones. This can be used to optimize generators for using slower generators less frequently.

🚧

Premature Optimization

It is best to only use this when you actually identify a case of specs being bottlenecked by a slow generator. As all optimizations, this one is a trade-off and should only be used when necessary.

qc.except(generator, values...)

Runs the generator passed to it as normal, but when it generates one of the values passed to it, it will try the generator again to guarantee that the generator will generate a value other then any of the values.

So qc.except(qc.uint, 0)(size) will generate a natural number, since qc.uint it will generate a random positive integer, and if it generates 0, it will try again.

This is quite a naive implementation as it will simply try again if the generator does generate one of the values. If the probability of generating one of these values is high, this can really kill performance, so for those cases a custom implementation might be better.

// bad
qc.except(qc.int.between(1, 3), 2);
// good
qc.pick(1, 3);
# bad
qc.except(qc.int.between(1, 3), 2)
# good
qc.pick(1, 3)
// bad
qc.except(qc.int.between(1, 3), 2);
// good
qc.pick(1, 3);