### Example Configuration Output Source: https://github.com/emil-e/rapidcheck/blob/master/doc/configuration.md When RapidCheck initializes, it displays the active configuration, excluding default values. This output can be used to reproduce specific test runs. ```text Using configuration: seed=8482903616249937941 ``` -------------------------------- ### Install RapidCheck Google Mock Listener Source: https://github.com/emil-e/rapidcheck/blob/master/doc/gmock.md Include the RapidCheck gmock header and install the listener after Google Mock initialization. This translates mock failures into RapidCheck failures. ```C++ #include // Here is where Google Mock integration lives #include int main(int argc, char **argv) { ::testing::InitGoogleMock(&argc, argv); // This installs the RapidCheck listener. rc::gmock::RapidCheckListener::install(); return RUN_ALL_TESTS(); } ``` -------------------------------- ### CMakeLists.txt Configuration for Counter Example Source: https://github.com/emil-e/rapidcheck/blob/master/examples/counter/CMakeLists.txt Configures the CMake build system to create an executable named 'counter' from 'main.cpp', links it with the 'rapidcheck' library, and includes the 'catch/include' directory for private use. ```cmake add_executable(counter main.cpp) target_link_libraries(counter rapidcheck) target_include_directories(counter PRIVATE ../../ext/catch/include) ``` -------------------------------- ### Generate Initialization Parameters for State Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state.md Use RapidCheck properties to generate initialization data for your model and state. This example shows how to generate a map of strings for initializing a FastKvStoreModel and FastKvStore. ```cpp rc::check([](const std::map &data) { FastKvStoreModel initialState; initialState.data = data; FastKvStore sut(data); rc::state::check(initialState, sut, &rc::state::gen::execOneOf); }); ``` -------------------------------- ### Implement Remove Command for FastKvStore Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state.md Example implementation of a `Remove` command for a `FastKvStore`. It includes `checkPreconditions` to ensure the key exists, `apply` to modify the model state, `run` to interact with the SUT and assert the outcome, and `show` for displaying the command. ```C++ struct Remove : rc::state::Command { std::string key; void checkPreconditions(const FastKvStoreModel &s0) const override { RC_PRE(s0.data.count(key) != 0); } void apply(FastKvStoreModel &s0) const override { s0.data.erase(key); } void run(const FastKvStoreModel &s0, FastKvStore &sut) const override { sut.remove(key); RC_ASSERT(!sut.hasKey(key)); } void show(std::ostream &os) const override { os << "Remove(" << key << ")"; } }; ``` -------------------------------- ### Google Mock Integration with RapidCheckListener Source: https://context7.com/emil-e/rapidcheck/llms.txt Translate Google Mock expectation failures into RapidCheck property failures using rc::gmock::RapidCheckListener. Install the listener after initializing Google Mock. ```cpp #include #include #include #include class Printer { public: virtual ~Printer() = default; virtual void print(const std::string &msg) = 0; }; class MockPrinter : public Printer { public: MOCK_METHOD(void, print, (const std::string &msg), (override)); }; RC_GTEST_PROP(MockTests, printerCalledWithEachElement, (const std::vector &msgs)) { MockPrinter mock; for (const auto &m : msgs) { EXPECT_CALL(mock, print(m)).Times(1); } for (const auto &m : msgs) { mock.print(m); } } int main(int argc, char **argv) { ::testing::InitGoogleMock(&argc, argv); rc::gmock::RapidCheckListener::install(); // must be called after InitGoogleMock return RUN_ALL_TESTS(); } // Note: do NOT pass --gtest_throw_on_failure; the listener handles failure translation // Build: target_link_libraries(tests rapidcheck_gtest rapidcheck_gmock gmock) ``` -------------------------------- ### Check Preconditions with RC_PRE Source: https://github.com/emil-e/rapidcheck/blob/master/doc/properties.md Use the `RC_PRE` macro within a property to enforce preconditions. If a precondition fails, the test case is discarded, and RapidCheck tries again with different inputs. This example ensures the string length is even before proceeding. ```C++ rc::check([](const std::string &str) { RC_PRE((str.size() % 2) == 0); // ... }); ``` -------------------------------- ### Pick Sized Element from Container Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators_ref.md Randomly selects an element from an initial segment of a container, proportional to the container's size. Elements are considered to increase in size from start to end. ```C++ const auto digit = *gen::sizedElementOf(std::string("0123456789")); ``` -------------------------------- ### Generate Containers with `rc::gen::container` Source: https://context7.com/emil-e/rapidcheck/llms.txt Generates containers (vector, list, set, map, etc.) whose elements come from a given generator. Overloads accept an optional fixed element count; without one, size scales with the implicit size parameter. Examples include variable-length vectors, fixed-size vectors, and maps with specific key/value generators. ```cpp #include #include #include #include int main() { // Variable-length vector of ints in [0, 100) rc::check("all elements are in range", []() { auto v = *rc::gen::container>( rc::gen::inRange(0, 100)); for (int x : v) { RC_ASSERT(x >= 0 && x < 100); } }); // Fixed-size container: exactly 5 elements rc::check("fixed-size vector always has 5 elements", []() { auto v = *rc::gen::container>( 5, rc::gen::arbitrary()); RC_ASSERT(v.size() == 5); }); // Map: keys and values from specific generators rc::check("map keys are non-empty strings", []() { auto m = *rc::gen::container>( rc::gen::nonEmpty(rc::gen::arbitrary()), rc::gen::arbitrary()); for (const auto &kv : m) { RC_ASSERT(!kv.first.empty()); } }); return 0; } ``` -------------------------------- ### Generate Bounded Numeric Values with `rc::gen::inRange` Source: https://context7.com/emil-e/rapidcheck/llms.txt Generates integers or other ordered values within `[min, max)`. This is useful for constraining numeric inputs to valid domain ranges without using preconditions, which discard tests. The example demonstrates generating a valid index for an array and the sum of two positive integers. ```cpp #include int main() { rc::check("index is always valid for a 10-element array", []() { const std::array arr = {0,1,2,3,4,5,6,7,8,9}; auto idx = *rc::gen::inRange(0, arr.size()); RC_ASSERT(idx < arr.size()); RC_ASSERT(arr[idx] == static_cast(idx)); }); // Combine with other generators rc::check("sum of two positive ints is positive", []() { int a = *rc::gen::inRange(1, 1000); int b = *rc::gen::inRange(1, 1000); RC_ASSERT(a + b > 0); }); return 0; } ``` -------------------------------- ### Define a Basic Property with rc::check Source: https://github.com/emil-e/rapidcheck/blob/master/doc/properties.md Use `rc::check` with a lambda to define a property. The lambda receives generated inputs and should return `true` for success or `false` for failure. This example checks the relationship between `std::string::empty()` and `std::string::size()`. ```C++ rc::check([](const std::string &str) { return str.empty() == (str.size() == 0); }); ``` -------------------------------- ### void runAll(Commands commands, Model state, Sut &sut) Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Runs the given commands in sequence on the given System Under Test assuming it is equivalent to the given model state. ```APIDOC ## void runAll(Commands commands, Model state, Sut &sut) ### Description Runs the given commands in sequence on the given System Under Test assuming it is equivalent to the given model state. There are two overloads, one that takes the state as an immediate value and and another that takes a callable that returns the state. ``` -------------------------------- ### Dependent Generator Values Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators.md Parameters of a generator can depend on values generated by other generators. This example generates an arbitrary integer `max` and then uses it as the upper bound for another generator. ```C++ const auto max = *rc::gen::arbitrary(); const auto i = *rc::gen::inRange(0, max); ``` -------------------------------- ### void runAll(Commands commands, MakeModel makeState, Sut &sut) Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Runs the given commands in sequence on the given System Under Test assuming it is equivalent to the given model state. ```APIDOC ## void runAll(Commands commands, MakeModel makeState, Sut &sut) ### Description Runs the given commands in sequence on the given System Under Test assuming it is equivalent to the given model state. There are two overloads, one that takes the state as an immediate value and and another that takes a callable that returns the state. ``` -------------------------------- ### virtual void run(const Model &s0, Sut &sut) const Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Applies this command to the given System Under Test. The state before this command has been applied is also passed in. This is the method in which to place your assertions. ```APIDOC ## virtual void run(const Model &s0, Sut &sut) const ### Description Applies this command to the given System Under Test. The state before this command has been applied is also passed in. If you need the post state, you can get this using the `nextState` convenience method. This is the method in which to place your assertions (`RC_ASSERT` et al.). This method is intended to be overridden but has a default implementation that does nothing. While the model state is passed as `const`, this doesn't prevent modification of the model if it, for example, is a `shared_ptr` or similar. Regardless, modifying the model state in this method leads to undefined behavior. ``` -------------------------------- ### RapidCheck Give Up Message Source: https://github.com/emil-e/rapidcheck/blob/master/doc/properties.md This is an example of the output displayed when RapidCheck gives up due to excessive discarded test cases. It indicates the number of successful tests and the specific condition that caused the last discard. ```text Gave up after 84 tests ../examples/newgen/main.cpp:10: RC_PRE(l0.size() < 4) Expands to: 18 < 4 ``` -------------------------------- ### Run State Check with rc::state::check Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state.md Demonstrates how to use `rc::state::check` within a RapidCheck property to test a `FastKvStore`. It initializes the model and SUT, and provides a generator for commands using `rc::state::gen::execOneOf`. ```C++ #include //... rc::check([] { FastKvStoreModel initialState; FastKvStore sut; rc::state::check(initialState, sut, &rc::state::gen::execOneOf); }); ``` -------------------------------- ### void applyAll(Commands commands, Model &state) Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Applies the given commands in sequence to the given model state. ```APIDOC ## void applyAll(Commands commands, Model &state) ### Description Applies the given commands in sequence to the given model state. ``` -------------------------------- ### void check(MakeModel makeInitialState, Sut sut, GenFunc f) Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Generates a valid command sequence for an initial state and then runs that sequence on sut. Any assertions triggered when running the command sequence will cause the property to fail. This function must be used inside a property. ```APIDOC ## void check(MakeModel makeInitialState, Sut sut, GenFunc f) ### Description Generates a valid command sequence for an initial state and then runs that sequence on `sut`. Any assertions triggered when running the command sequence will cause the property to fail. For more information about the generation function parameter, see `rc::state::gen::commands`. There are two overloads, one that takes the initial state as an immediate value and and another that takes a callable that returns the initial state. This function must be used inside a property, it cannot be used standalone. ``` -------------------------------- ### Define Custom Arbitrary Type Generator for `Person` Source: https://context7.com/emil-e/rapidcheck/llms.txt Specialize `rc::Arbitrary` to teach RapidCheck how to generate arbitrary values of a custom type. This allows the custom type to be used as a property parameter and with generator combinators. The example shows generating a `Person` struct with bounded age. ```cpp #include #include struct Person { std::string firstName; std::string lastName; int age; }; namespace rc { template <> struct Arbitrary { static Gen arbitrary() { return gen::build( gen::set(&Person::firstName), // uses Arbitrary gen::set(&Person::lastName), // uses Arbitrary gen::set(&Person::age, gen::inRange(0, 120))); // bounded int } }; } // namespace rc int main() { rc::check("person age is always in valid range", [](const Person &p) { RC_ASSERT(p.age >= 0); RC_ASSERT(p.age < 120); }); // Custom type also works with containers automatically rc::check("list of persons is non-negative in count", [](const std::vector &people) { RC_ASSERT(people.size() >= 0); }); return 0; } ``` -------------------------------- ### Include Doctest and Rapidcheck Headers Source: https://github.com/emil-e/rapidcheck/blob/master/doc/doctest.md Include the necessary headers for doctest, rapidcheck, and the rapidcheck doctest integration. ```cpp #include #include "rapidcheck.h" #include "rapidcheck/doctest.h" ``` -------------------------------- ### void check(Model initialState, Sut sut, GenFunc f) Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Generates a valid command sequence for an initial state and then runs that sequence on sut. Any assertions triggered when running the command sequence will cause the property to fail. This function must be used inside a property. ```APIDOC ## void check(Model initialState, Sut sut, GenFunc f) ### Description Generates a valid command sequence for an initial state and then runs that sequence on `sut`. Any assertions triggered when running the command sequence will cause the property to fail. For more information about the generation function parameter, see `rc::state::gen::commands`. There are two overloads, one that takes the initial state as an immediate value and and another that takes a callable that returns the initial state. This function must be used inside a property, it cannot be used standalone. ``` -------------------------------- ### Stateful Testing with rc::state::Command Source: https://context7.com/emil-e/rapidcheck/llms.txt Define a model and commands to test stateful systems. RapidCheck generates and shrinks command sequences, comparing model and SUT behavior. ```cpp #include #include #include #include #include // Simple in-memory key-value store (system under test) class KvStore { std::map data_; public: void put(const std::string &k, const std::string &v) { data_[k] = v; } std::string get(const std::string &k) const { return data_.at(k); } bool has(const std::string &k) const { return data_.count(k) > 0; } void remove(const std::string &k) { data_.erase(k); } }; // Model: plain struct mirroring expected state struct KvModel { std::map data; }; using KvCmd = rc::state::Command; // Put command struct Put : KvCmd { std::string key, value; Put() : key(*rc::gen::arbitrary()), value(*rc::gen::arbitrary()) {} void apply(KvModel &m) const override { m.data[key] = value; } void run(const KvModel &, KvStore &sut) const override { sut.put(key, value); RC_ASSERT(sut.has(key)); RC_ASSERT(sut.get(key) == value); } void show(std::ostream &os) const override { os << "Put(" << key << ", " << value << ")"; } }; // Get command (only when key exists) struct Get : KvCmd { std::string key; void checkPreconditions(const KvModel &m) const override { RC_PRE(!m.data.empty()); // pick key from existing keys key = *rc::gen::elementOf(m.data) .map([](const auto &kv) { return kv.first; }); } void apply(KvModel &) const override {} void run(const KvModel &m, KvStore &sut) const override { RC_ASSERT(sut.has(key)); RC_ASSERT(sut.get(key) == m.data.at(key)); } void show(std::ostream &os) const override { os << "Get(" << key << ")"; } }; // Remove command struct Remove : KvCmd { std::string key; void checkPreconditions(const KvModel &m) const override { RC_PRE(!m.data.empty()); key = *rc::gen::elementOf(m.data) .map([](const auto &kv) { return kv.first; }); } void apply(KvModel &m) const override { m.data.erase(key); } void run(const KvModel &, KvStore &sut) const override { sut.remove(key); RC_ASSERT(!sut.has(key)); } void show(std::ostream &os) const override { os << "Remove(" << key << ")"; } }; int main() { rc::check("KvStore behaves according to model", [] { KvModel initialState; KvStore sut; rc::state::check(initialState, sut, rc::state::gen::execOneOfWithArgs()); }); // On failure, output shows the minimal failing command sequence, e.g.: // Counterexample: // Put("a", "1"), Put("a", "2"), Get("a") // RC_ASSERT(sut.get(key) == m.data.at(key)) // Expands to: "1" == "2" return 0; } ``` -------------------------------- ### Build objects by setting members Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators_ref.md Use `build` with `gen::set` to construct objects and then set their members or call member functions using specified generators. This allows for fine-grained control over object creation. ```C++ const auto person = *gen::build(gen::construct(genName()), gen::set(&Person::age, gen::inRange(0, 100)), gen::set(&Person::phoneNumber), gen::set(&Person::setGender, gen::element(std::string("Male"), std::string("Female"))), gen::set(&Person::setAddress, gen::tuple( genCity(), genStreet(), genZipCode()))); ``` -------------------------------- ### virtual void apply(Model &s0) const Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Applies this command to the given state. The effect of this command on the model should be equivalent to this commands effect on the System Under Test. This method is intended to be overridden but has a default implementation that does nothing. ```APIDOC ## virtual void apply(Model &s0) const ### Description Applies this command to the given state. The effect of this command on the model should be equivalent to this commands effect on the System Under Test. This method is intended to be overridden but has a default implementation that does nothing, something that can be useful for commands that do not modify state. While the model state is passed as `const`, this doesn't prevent modification of the model if it, for example, is a `shared_ptr` or similar. Regardless, modifying the model state in this method leads to undefined behavior. ``` -------------------------------- ### virtual void checkPreconditions(const Model &s0) const Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md If your command is not valid for all states, you must implement this method to assert preconditions. Preconditions can be asserted using any of the discarding macros such as `RC_PRE` or `RC_DISCARD`. ```APIDOC ## virtual void checkPreconditions(const Model &s0) const ### Description If your command is not valid for all states, you must implement this method to assert preconditions. Preconditions can be asserted using any of the discarding macros such as `RC_PRE` or `RC_DISCARD`. If the command is discarded, RapidCheck will simply try to generate a new one. This method is intended to be overridden but has a default implementation that does nothing which is what you want if your command has no preconditions. While the model state is passed as `const`, this doesn't prevent modification of the model if it, for example, is a `shared_ptr` or similar. Regardless, modifying the model state in this method leads to undefined behavior. ``` -------------------------------- ### virtual void show(std::ostream &os) const Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Outputs a string representation of the command to the given output stream. The default implementation outputs the type name. ```APIDOC ## virtual void show(std::ostream &os) const ### Description Outputs a string representation of the command to the given output stream. The default implementation outputs the type name (via RTTI) but if your command has any sort of parameters, you will likely want to override this with a custom implementation to include those. ``` -------------------------------- ### Define Executable and Link Libraries Source: https://github.com/emil-e/rapidcheck/blob/master/extras/gmock/test/CMakeLists.txt Defines the test executable and links it with required libraries including GMock, Rapidcheck, and Catch2. Ensure these libraries are available in your build environment. ```cmake add_executable(rapidcheck_gmock_tests main.cpp) target_link_libraries(rapidcheck_gmock_tests rapidcheck_gmock rapidcheck_catch Catch2::Catch2 gmock) ``` -------------------------------- ### Define Executable and Link Libraries Source: https://github.com/emil-e/rapidcheck/blob/master/examples/boost_test/CMakeLists.txt Defines the main executable for integration tests and links it against the necessary Boost.Test and Boost libraries. ```cmake add_executable(boost_test_integration main.cpp) target_link_libraries(boost_test_integration rapidcheck_boost_test boost) ``` -------------------------------- ### Link Libraries for Boost Tests Source: https://github.com/emil-e/rapidcheck/blob/master/extras/boost/test/CMakeLists.txt Links the necessary libraries to the test executable. This includes Boost, Rapidcheck Boost integration, Rapidcheck Catch integration, Rapidcheck test utilities, and the Catch2 testing framework. ```cmake target_link_libraries(rapidcheck_boost_tests boost rapidcheck_boost rapidcheck_catch rapidcheck_test_utils Catch2::Catch2) ``` -------------------------------- ### Generate Commands with a State-Generating Callable Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md This overload of `gen::commands` accepts a callable that produces the initial model state, useful when the state itself needs to be generated. The `GenFunc` then operates on this generated state. ```cpp rc::state::check( [] { return MyModel(); }, sut, [](const MyModel &state) { return rc::state::gen::execOneOfWithArgs()(state); }); ``` -------------------------------- ### Gen build(Bindings... bindings) Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators_ref.md Generates objects of type T by default constructing T and then applying specified member bindings. ```APIDOC ## `Gen build(Bindings... bindings)` ### Description Like `build(Gen gen, Bindings... bindings)` but `T` is default constructed. Since no generator is specified, `T` cannot be deduced and must be explicitly specified. ``` -------------------------------- ### Define Executable and Link Libraries Source: https://github.com/emil-e/rapidcheck/blob/master/examples/database/CMakeLists.txt This snippet defines an executable target named 'database' with its source files and links it against the 'rapidcheck' library. Use this to build your C++ application. ```cmake add_executable(database main.cpp Database.cpp DatabaseConnection.cpp User.cpp) target_link_libraries(database rapidcheck) ``` -------------------------------- ### Generate Commands for Non-Copyable Models Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md When the model is non-copyable, use a lambda with `gen::execOneOfWithArgs` to pass copyable values derived from the model state to the command constructors. This allows commands to be constructed with necessary state information. ```cpp MySut sut; rc::state::check( [] { return MyNonCopyableModel(); }, sut, [](const MyNonCopyableModel &state) { return rc::state::gen::execOneOfWithArgs()( state.status(), state.remaining()); }); ``` -------------------------------- ### Gen build(Gen gen, Bindings... bindings) Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators_ref.md Generates objects of type T by first constructing an initial object using 'gen' and then applying specified member bindings. ```APIDOC ## `Gen build(Gen gen, Bindings... bindings)` ### Description Generates objects of type `T` by setting members of the object according to the specified bindings. A binding is created using `gen::set(Member member, Gen gen)`. `Member` should be a pointer to a member of that object and `gen` should be an appropriate generator for the type of the member. The member may be one of: - A member variable in which case `gen` should be a generator for the type of that variable. - A member function that takes a single argument. `gen` should be a generator for the type of that argument. - A member function that takes multiple arguments. `gen` should be a generator of tuples matching those arguments. The generator may be omitted in which case `gen::arbitrary()` will be used where `T` is the appropriate type of the generator. The initial value is generated by the specified generator after which the bindings are applied. ### Example ```C++ const auto person = *gen::build(gen::construct(genName()), gen::set(&Person::age, gen::inRange(0, 100)), gen::set(&Person::phoneNumber), gen::set(&Person::setGender, gen::element(std::string("Male"), std::string("Female"))), gen::set(&Person::setAddress, gen::tuple( genCity(), genStreet(), genZipCode()))); ``` ``` -------------------------------- ### Integrate RapidCheck with CMake Source: https://github.com/emil-e/rapidcheck/blob/master/README.md Add RapidCheck as a subdirectory to your CMake project and link against the rapidcheck target for both linking and include directories. ```cmake add_subdirectory("path/to/rapidcheck") target_link_libraries(my_target rapidcheck) ``` -------------------------------- ### Construct Objects with `rc::gen::construct` and `rc::gen::build` Source: https://context7.com/emil-e/rapidcheck/llms.txt Use `construct` to call a type's constructor directly with generated arguments. Use `build` with `rc::gen::set` for member-wise initialization, suitable for types with default constructors and public members or setters. ```cpp #include #include struct Point { int x, y; }; struct Config { std::string host; int port; bool secure; }; int main() { // construct: calls constructor directly rc::check("point coordinates match generators", []() { auto p = *rc::gen::construct( rc::gen::inRange(-100, 100), rc::gen::inRange(-100, 100)); RC_ASSERT(p.x >= -100 && p.x < 100); RC_ASSERT(p.y >= -100 && p.y < 100); }); // build: member setters (gen::set with member pointer) rc::check("config has valid port range", []() { auto cfg = *rc::gen::build( rc::gen::set(&Config::host, rc::gen::nonEmpty(rc::gen::arbitrary())), rc::gen::set(&Config::port, rc::gen::inRange(1, 65536)), rc::gen::set(&Config::secure, rc::gen::arbitrary())); RC_ASSERT(cfg.port >= 1 && cfg.port < 65536); RC_ASSERT(!cfg.host.empty()); }); return 0; } ``` -------------------------------- ### Pick Element with Weights Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators_ref.md Selects an element from a list of pairs, where each pair contains a weight and an element. The probability of selecting an element is proportional to its weight. ```C++ const auto animal = *gen::weightedElement({ {4, std::string("horse")}, {2, std::string("donkey")}, {1, std::string("zebra")}}); ``` -------------------------------- ### Define a Command with Constructor Arguments Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Define a command struct that accepts constructor arguments, such as the model state. This is useful when using `gen::execOneOfWithArgs` to pass specific state information to the command's constructor. ```cpp struct Take : rc::state::Command { std::string item; explicit Take(const MyModel &s0) : item(*rc::gen::elementOf(s0.items)) {} // ... }; ``` -------------------------------- ### Naming Generators with `as` Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators.md Use the `as` method to attach a name to a generator. This name will be used instead of the type when printing counterexamples, improving clarity. ```C++ auto elements = *gen::arbitrary>().as("elements"); const auto indexIntoElements = gen::inRange(0, elements.size()).as("index into elements"); const auto a = *indexIntoElements; const auto b = *indexIntoElements; ``` -------------------------------- ### RapidCheck Assertion Macros Showcase Source: https://context7.com/emil-e/rapidcheck/llms.txt Utilize assertion macros like `RC_ASSERT`, `RC_ASSERT_FALSE`, `RC_ASSERT_THROWS`, `RC_ASSERT_THROWS_AS`, `RC_SUCCEED_IF`, `RC_PRE`, and `RC_FAIL` for robust property-based testing. These macros provide detailed failure output and support shrinking. ```cpp #include #include #include int main() { rc::check("assertion macro showcase", [](int a, int b, const std::string &s) { // RC_ASSERT: fails property if expression is false RC_ASSERT(a + b == b + a); // RC_ASSERT_FALSE: fails if expression is true RC_ASSERT_FALSE(a != a); // RC_ASSERT_THROWS: fails if no exception thrown RC_ASSERT_THROWS([]{ throw std::runtime_error("boom"); }()); // RC_ASSERT_THROWS_AS: fails if wrong exception type RC_ASSERT_THROWS_AS( []{ throw std::out_of_range("oob"); }(), std::out_of_range); // RC_SUCCEED_IF: immediately pass if condition holds RC_SUCCEED_IF(s.empty()); // skip further checks for empty strings // RC_PRE: discard test case if precondition not met RC_PRE(s.size() > 1); // RC_FAIL: unconditionally fail with message if (s == "__invalid__") RC_FAIL("Got reserved string!"); }); // Output on failure of RC_ASSERT(a + b == b + a) with hypothetical bug: // main.cpp:10: // RC_ASSERT(a + b == b + a) // Expands to: // 3 == 2 return 0; } ``` -------------------------------- ### Create Generator with Size - C++ Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators_ref.md Use `gen::withSize` to create a generator that depends on the current generation size. The provided callable receives the size and must return a generator. ```C++ const auto sizedInt = *gen::withSize([](int size) { return gen::inRange(0, size); }); ``` -------------------------------- ### Generate a Sequence of Commands Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Use the `gen::commands` function to generate a valid sequence of commands for a given model state. The `GenFunc` argument should return a generator for commands, and `RapidCheck` will handle discarding invalid commands. ```cpp rc::state::check(initialState, sut, rc::state::gen::commands(initialState, [](const MyModel &state) { return rc::state::gen::execOneOfWithArgs()(state); })); ``` -------------------------------- ### Doctest Integration with rc::doctest::check Source: https://context7.com/emil-e/rapidcheck/llms.txt Execute RapidCheck properties within Doctest TEST_CASE blocks using rc::doctest::check. Ensure Doctest and RapidCheck headers are included. ```cpp #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include #include #include TEST_CASE("integer arithmetic") { rc::doctest::check("addition is commutative", [](int a, int b) { return a + b == b + a; }); rc::doctest::check("subtraction inverts addition", [](int a, int b) { RC_ASSERT((a + b) - b == a); }); } TEST_CASE("string properties") { rc::doctest::check("string copy is identical", [](const std::string &s) { RC_ASSERT(std::string(s) == s); }); } // Build: target_link_libraries(tests rapidcheck_doctest) ``` -------------------------------- ### Generate Commands with Specific Constructors Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Use `gen::execOneOfWithArgs` to create a generator that randomly constructs commands from a list of types, utilizing constructors that match provided arguments. This is typically used with `rc::state::gen::commands` or `rc::state::check`. ```cpp MyModel initialState; MySut sut; rc::state::check(initialState, sut, rc::state::gen::execOneOfWithArgs()); ``` -------------------------------- ### Include GMock and Googletest Directories Source: https://github.com/emil-e/rapidcheck/blob/master/extras/gmock/test/CMakeLists.txt Specifies private include directories for GMock and Googletest. This ensures the compiler can find the necessary header files for these libraries. ```cmake target_include_directories(rapidcheck_gmock_tests PRIVATE ${CMAKE_SOURCE_DIR}/ext/googletest/googletest/include ${CMAKE_SOURCE_DIR}/ext/googletest/googlemock/include) ``` -------------------------------- ### Model nextState(const Model &s0) const Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state_ref.md Convenience method that calls `apply` on a copy of the given state and returns it. Cannot be overridden, override `apply` instead. ```APIDOC ## Model nextState(const Model &s0) const ### Description Convenience method that calls `apply` on a copy of the given state and returns it. Saves some keystrokes occasionally since you don't have to allocate a model on the stack. Cannot be overridden, override `apply` instead. This method does not work for non-copyable models. ``` -------------------------------- ### Reproduce Failure with Seed in Shell Source: https://github.com/emil-e/rapidcheck/blob/master/doc/debugging.md Rerun the test program with the exact seed printed by RapidCheck to reproduce a specific test run. ```shell RC_PARAMS="seed=12776003016957408636" ./my_test ``` -------------------------------- ### Execute Custom Logic for Generation - C++ Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators_ref.md Use `gen::exec` to create a generator by executing a callable. This callable can use other generators and its return value is the generated value. Be aware of potential performance implications compared to other combinators. ```C++ const auto name = *gen::exec([](const Address &address) { const auto gender = *gen::element(kMale, kFemale); const auto name = *genName(gender); return Person(name, gender, address); }); ``` -------------------------------- ### Generate from a sized list of elements Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators_ref.md Use `sizedElement` to pick a random element from a list of provided values, respecting the current generation size. ```C++ const auto digit = *gen::sizedElement( std::string("one"), std::string("two"), std::string("three")); ``` -------------------------------- ### Choose from generators with `rc::gen::oneOf` and `rc::gen::elementOf` Source: https://context7.com/emil-e/rapidcheck/llms.txt `oneOf` picks uniformly from multiple generators. `elementOf` picks from an existing container. `weightedOneOf` and `weightedElement` support non-uniform distributions. ```cpp #include #include #include int main() { // Pick from multiple generators with equal probability rc::check("value is always small or large", []() { int n = *rc::gen::oneOf(rc::gen::inRange(0, 10), rc::gen::inRange(1000, 2000)); RC_ASSERT((n >= 0 && n < 10) || (n >= 1000 && n < 2000)); }); // Pick an element from a known set const std::vector colors = {"red", "green", "blue"}; rc::check("element is always from the set", [&colors]() { std::string c = *rc::gen::elementOf(colors); RC_ASSERT(c == "red" || c == "green" || c == "blue"); }); // Weighted choice: 70% positive, 30% negative rc::check("weighted: mostly positive numbers", []() { // Use weightedOneOf for non-uniform generator selection int n = *rc::gen::weightedOneOf( {7, rc::gen::positive()}, {3, rc::gen::negative()}); (void)n; // just ensure it compiles and generates }); return 0; } ``` -------------------------------- ### Generate Strings Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators_ref.md Generates strings efficiently. For custom character generation within strings, use `gen::container`. ```C++ const auto s = *gen::string(); ``` -------------------------------- ### Catch2 Integration with rc::prop Source: https://context7.com/emil-e/rapidcheck/llms.txt Run RapidCheck properties within Catch2 TEST_CASE blocks using rc::prop. Include Catch2 and RapidCheck headers. ```cpp #define CATCH_CONFIG_MAIN #include #include #include #include #include TEST_CASE("String properties") { rc::prop("copy of string equals original", [](const std::string &s) { RC_ASSERT(std::string(s) == s); }); rc::prop("concatenation length is sum of lengths", [](const std::string &a, const std::string &b) { RC_ASSERT((a + b).size() == a.size() + b.size(); }); } TEST_CASE("Vector properties") { rc::prop("sorting is idempotent", [](std::vector v) { std::sort(v.begin(), v.end()); auto once = v; std::sort(v.begin(), v.end()); RC_ASSERT(v == once); }); } // Build: target_link_libraries(tests rapidcheck_catch) ``` -------------------------------- ### Conditional Boost Integration Source: https://github.com/emil-e/rapidcheck/blob/master/ext/CMakeLists.txt Integrates Boost if RC_ENABLE_BOOST and RC_ENABLE_TESTS are defined. It downloads Boost if not present and configures it as an interface library. ```cmake if (RC_ENABLE_BOOST AND RC_ENABLE_TESTS) if (NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/boost") execute_process( COMMAND "sh" "get_boost.sh" WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}") endif() add_library(boost INTERFACE) target_include_directories(boost INTERFACE boost) endif() ``` -------------------------------- ### Configuring Rapidcheck via RC_PARAMS Environment Variable Source: https://context7.com/emil-e/rapidcheck/llms.txt Adjust test behavior at runtime by setting the RC_PARAMS environment variable. No code changes are needed. This is useful for debugging, CI, or reproduction. ```bash # Run with a fixed seed to reproduce a prior failure exactly RC_PARAMS="seed=12776003016957408636" ./my_tests # Run 500 tests with size capped at 50 RC_PARAMS="max_success=500 max_size=50" ./my_tests # Disable shrinking for faster iteration during development RC_PARAMS="noshrink=1" ./my_tests # Show progress indicators during runs RC_PARAMS="verbose_progress=1 verbose_shrinking=1" ./my_tests # Reproduce a specific failure using the opaque reproduce string from output # (printed by RapidCheck when a failure occurs) RC_PARAMS="reproduce=CAAAAAAAAAAFAAAABAAAAAwAAAA..." ./my_tests ``` ```cpp // Available parameters and their defaults: // seed - 64-bit unsigned int; auto-generated if unset // max_success - int, default 100 (number of successful tests to run) // max_size - int, default 100 (maximum generation size) // max_discard_ratio- int, default 10 (max discards per successful test) // noshrink - 0 or 1, default 0 (1 = disable shrinking) // verbose_progress - 0 or 1, default 0 (show '.' per test, '!' per shrink) // verbose_shrinking- 0 or 1, default 0 (show each shrink attempt) // reproduce - opaque string from failure output ``` -------------------------------- ### Run a Property Test with rc::check Source: https://context7.com/emil-e/rapidcheck/llms.txt Use rc::check to run a property test with randomly generated inputs. Properties can be simple lambdas returning void and using RC_ASSERT, or lambdas returning bool. ```cpp #include #include #include int main() { // Simple property: reversing a vector twice yields the original rc::check("double reversal yields the original value", [](const std::vector &l0) { auto l1 = l0; std::reverse(begin(l1), end(l1)); std::reverse(begin(l1), end(l1)); RC_ASSERT(l0 == l1); }); // Property returning bool instead of using RC_ASSERT rc::check("addition is commutative", [](int a, int b) { return (a + b) == (b + a); }); // Property with precondition: only test even-length strings rc::check("even-length string stays even after append-of-two", [](const std::string &s) { RC_PRE((s.size() % 2) == 0); RC_ASSERT((s + s).size() % 2 == 0); }); return 0; } // Success output: // Using configuration: seed=9928307433081493900 // - double reversal yields the original value // OK, passed 100 tests // // Failure output (hypothetical bug): // Falsifiable after 12 tests and 10 shrinks // std::tuple>: // ([1, 0, 0, 0, 0, 0, 0, 0, 0, 0]) // main.cpp:17: // RC_ASSERT(l0 == l1) // Expands to: // [1, 0, 0, 0, 0, 0, 0, 0, 0, 0] == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ``` -------------------------------- ### Gen withSize(Callable callable) Source: https://github.com/emil-e/rapidcheck/blob/master/doc/generators_ref.md Creates a generator that takes the current size as input and returns a generator based on that size. Useful for size-dependent generation. ```APIDOC ## `Gen withSize(Callable callable)` ### Description Creates a generator by taking a callable which gets passed the current size and is expected to return a generator. The type of the returned generator will be the same as the type returned by `callable`. ### Example ```C++ const auto sizedInt = *gen::withSize([](int size) { return gen::inRange(0, size); }); ``` ``` -------------------------------- ### Test remove method of FastKvStore Source: https://github.com/emil-e/rapidcheck/blob/master/doc/state.md Tests the `remove` method of a key-value store by constructing it with arbitrary data and then removing a key. Asserts that the key is no longer present. ```C++ rc::check("remove(std::string) retrieves the value of a key", [](const std::map &data) { FastKvStore store(data); const auto key = *rc::gen::elementOf(data).first; store.remove(key); RC_ASSERT(!store.hasKey(key)); }); ``` -------------------------------- ### Control Generation Size with `rc::gen::resize`, `rc::gen::scale`, and `rc::gen::withSize` Source: https://context7.com/emil-e/rapidcheck/llms.txt Control the implicit size parameter used by generators. `resize` pins the size, `scale` multiplies it, and `withSize` provides direct access to the current size for building size-dependent generators. ```cpp #include #include int main() { // resize: always generate with size=10 regardless of test progression rc::check("small vector never exceeds ~10 elements (size-limited)", []() { auto v = *rc::gen::resize( 10, rc::gen::container>(rc::gen::arbitrary())); // at size=10, vector won't be excessively large (void)v; }); // scale: generate half-sized containers rc::check("half-scale container", []() { auto small = *rc::gen::scale( 0.5, rc::gen::container>(rc::gen::arbitrary())); (void)small; }); // withSize: manually use size parameter auto sizeAwareGen = rc::gen::withSize([](int size) { // Generate a vector whose max length equals current size return rc::gen::container>( size, rc::gen::arbitrary()); }); rc::check("size-aware vector has exactly 'size' elements", [&sizeAwareGen]() { auto v = *sizeAwareGen; (void)v; // length varies from 0..100 as tests progress }); return 0; } ```