diff --git a/docs/list-of-examples.md b/docs/list-of-examples.md index fd69cc84..642d4d23 100644 --- a/docs/list-of-examples.md +++ b/docs/list-of-examples.md @@ -14,6 +14,7 @@ - Configuration: [Provide your own output streams](../examples/231-Cfg-OutputStreams.cpp) - Generators: [Create your own generator](../examples/300-Gen-OwnGenerator.cpp) - Generators: [Use map to convert types in GENERATE expression](../examples/301-Gen-MapTypeConversion.cpp) +- Generators: [Run test with a table of input values](../examples/302-Gen-Table.cpp) - Generators: [Use variables in generator expressions](../examples/310-Gen-VariablesInGenerators.cpp) - Generators: [Use custom variable capture in generator expressions](../examples/311-Gen-CustomCapture.cpp) diff --git a/examples/302-Gen-Table.cpp b/examples/302-Gen-Table.cpp new file mode 100644 index 00000000..8b4fc974 --- /dev/null +++ b/examples/302-Gen-Table.cpp @@ -0,0 +1,55 @@ +// 302-Gen-Table.cpp +// Shows how to use table to run a test many times with different inputs. Lifted from examples on +// issue #850. + +#include +#include +#include + +struct TestSubject { + // this is the method we are going to test. It returns the length of the + // input string. + size_t GetLength( const std::string& input ) const { return input.size(); } +}; + + +TEST_CASE("Table allows pre-computed test inputs and outputs", "[example][generator]") { + using std::make_tuple; + // do setup here as normal + TestSubject subj; + + SECTION("This section is run for each row in the table") { + std::string test_input; + size_t expected_output; + std::tie( test_input, expected_output ) = + GENERATE( table( + { /* In this case one of the parameters to our test case is the + * expected output, but this is not required. There could be + * multiple expected values in the table, which can have any + * (fixed) number of columns. + */ + make_tuple( "one", 3 ), + make_tuple( "two", 3 ), + make_tuple( "three", 5 ), + make_tuple( "four", 4 ) } ) ); + + // run the test + auto result = subj.GetLength(test_input); + // capture the input data to go with the outputs. + CAPTURE(test_input); + // check it matches the pre-calculated data + REQUIRE(result == expected_output); + } // end section +} + +/* Possible simplifications where less legacy toolchain support is needed: + * + * - With libstdc++6 or newer, the make_tuple() calls can be ommitted + * (technically C++17 but does not require -std in GCC/Clang). See + * https://stackoverflow.com/questions/12436586/tuple-vector-and-initializer-list + * + * - In C++17 mode std::tie() and the preceeding variable delcarations can be + * replaced by structured bindings: auto [test_input, expected] = GENERATE( + * table({ ... + */ +// Compiling and running this file will result in 4 successful assertions diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index af34d437..b934aa7c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -32,6 +32,7 @@ set( SOURCES_IDIOMATIC_EXAMPLES 210-Evt-EventListeners.cpp 300-Gen-OwnGenerator.cpp 301-Gen-MapTypeConversion.cpp + 302-Gen-Table.cpp 310-Gen-VariablesInGenerators.cpp 311-Gen-CustomCapture.cpp )