Skip to content
graydon edited this page Nov 22, 2014 · 7 revisions

Arbitrary is the name (borrowed from QuickCheck) of the concept for test case generators. A test case is a set of parameters for a property; we represent them with std::tuple.

Arbitrary

concept Arbitrary {
  typedef ... result_type;
  bool operator() (value<result_type>& args);
};
  • typedef ... result_type; The type of the test case. Must be a std::tuple.

  • bool operator() (value<result_type>& args); The generating function. Carries a notion of failure. Returns false if no test case could be generated, e.g., because a limit has been reached. Otherwise, deposits a test case in args and returns true.

AutoCheck provides a standard model of Arbitrary:

template <typename... Gens>
class arbitrary {
  public:
    arbitrary(const Gens&... gens);

    typedef std::tuple<typename Gens::result_type...> result_type;
    bool operator() (value<result_type>& args);

    typedef bool (const typename Gens::result_type&...) premise_t;
    arbitrary& discard_if(const premise_t& pred);
    arbitrary& discard_at_most(size_t discards);
    arbitrary& resize(size_t resizer(size_t));
};
  • arbitrary(const Gens&... gens); Builds an arbitrary from component Generators: one for each value in a test case.

  • bool operator() (value<result_type>& args); In addition to modeling Arbitrary, handles the growth of test cases. The first test cases generated are small and grow gradually. See Generator for more detail.

  • typedef bool (const typename Gens::result_type&...) premise_t; A premise evaluates some Boolean condition over the test case.

  • arbitrary& discard_if(const premise_t& pred); Discards test cases that don't satisfy the premise. Returns *this to allow chaining.

  • arbitrary& discard_at_most(size_t discards); Limits the number of test cases that can be discarded. The default is 500.

  • arbitrary& resize(size_t resizer(size_t)); Stores a function to transform the size passed to the component generators.

Combinators

AutoCheck provides a few free functions to permit a more function style of building an Arbitrary:

template <typename Arbitrary>
Arbitrary&& only_if(const typename Arbitrary::premise_t& pred, Arbitrary&& arb);
// Requires the Arbitrary to expose a typedef for `premise_t`.
template <typename Arbitrary>
Arbitrary&& at_most(size_t discards, Arbitrary&& arb);
template <typename Arbitrary>
Arbitrary&& resize(size_t resizer(size_t), Arbitrary&& arb);
Clone this wiki locally