Gromacs  2025.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Functions | Variables
#include <algorithm>
#include <filesystem>
#include <functional>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
#include <gtest/gtest.h>
#include "gromacs/utility/enumerationhelpers.h"
#include "gromacs/utility/stringutil.h"
#include "testasserts.h"
+ Include dependency graph for naming.h:

Description

Functionality for customizing names of tests and the files containing their reference data in a declarative way.

To provide GoogleTest with helpfully customized names for test cases constructed via testing::TestWithParam<TestParameters>,

*
* //! Enumeration used as an element of the test parameter tuple
* enum class : int Flavor { A, B, C, Count };
* EnumerationArray<Flavor, const char*> sc_flavorName = { "A", "B", "C" };
*
* //! The test-parameter tuple
* std::tuple<int, std::string, Flavor, float> TestParameters;
* //! Parameterized test fixture
* class ExampleTest : public ::testing::TestWithParam<TestParameters> { };
*
* //! Functor containing tuple for naming each test case
* const NameOfTestFromTuple<TestParameters> sc_testNamer{
* std::make_tuple(PrefixFormatter<int, intToString>{"i_"},
* sc_flavorName,
*
* // Extra functor for further customizing the filename used for the
* // reference data, particularly useful when some parameters should
* // not influence the name of the file. See below for details.
* // This example makes reference-data filenames like
* // Combinations_ExampleTest_i_0_foo_3_1416.xml
* const RefDataFilenameMaker<TestParameters> sc_refDataFilenameMaker {
* std::make_tuple(PrefixFormatter<int, intToString>{"i_"},
* toEmptyString, // ignores the Flavor
*
* TEST_P(ExampleTest, Works)
* {
* // Use C++17 structured bindings to extract the test parameters
* auto [ intParam, stringParam, flavorParam, floatParam ] = GetParam();
* // Use the functor to name the reference data filename appropriately,
* // ie. where it is expected that Flavor does not change the values expected.
* TestReferenceData refData(sc_refDataFilenameMaker(GetParam()));
*
* // Go test things against the reference data
* // ...
* }
*
* // Use the functor to name the test cases
* INSTANTIATE_TEST_SUITE_P(Combinations, ExampleTest,
* ::testing::Combine(::testing::ValuesIn(0, 1, 3),
* ::testing::Values("foo", "bar"),
* ::testing::Values(Flavor::A, Flavor::B),
* ::testing::Values(3.1416, 2.7183)),
* sc_testNamer);
*
*

When passed, the sc_testNamer functor is called by GoogleTest to generate a unique name for the test, which is done by NameOfTestFromTuple<TestParamers> calling the formatters (passing the respective parameters) to construct an underscore-separated string as the test name.

Several helper functions have been provided to smooth common use cases, including

toEmptyString is particularly useful for the case where the test case needs reference data, but only a subset of the test parameters contribute to computing the expected result, while others specify the implementation (e.g. target hardware, or which sets of outputs are to be computed, or an implementation detail). To do this:

Alternatively, if the test author prefers to use a struct for parameters, the supporting machinery can be declared inside that struct for clarity, like

*
* //! The test parameters
* struct TestParameters
* {
* //! The test-parameter tuple, must match the layout of the rest of the class
* using ParametersTuple = std::tuple<int, std::string, Flavor, float>;
* //! Some int
* int i;
* // ... other parameters
* //! Tuple of formatters to name the parameterized test cases
* static const NameOfTestFromTuple<ParametersTuple> sc_testNamer;
* //! Tuple of formatters to name the test-case reference data uniquely enough
* static const RefDataFilenameMaker<ParametersTuple> sc_refDataFilenameMaker;
* };
* // Then define the static variables outside the class in the same manner as
* // above, as required by the language.
*
*
Author
Mark Abraham mark..nosp@m.j.ab.nosp@m.raham.nosp@m.@gma.nosp@m.il.co.nosp@m.m

Classes

struct  gmx::test::detail::FormatterVariant< T, Enable >
 Single-component variant for a formatting callable for variables of type T. More...
 
struct  gmx::test::detail::FormatterVariant< Enum, typename std::enable_if_t< std::is_enum_v< Enum > > >
 Specialization for formatting function of variables whose type is an enum. More...
 
struct  gmx::test::detail::ParamsToFormatterVariants< Tuple >
 Template for mapping parameter types to formatter variants. More...
 
struct  gmx::test::detail::ParamsToFormatterVariants< std::tuple< Ts...> >
 Specialization for tuple of parameter types to tuple of formatter variants. More...
 
struct  gmx::test::detail::IsTuple< T >
 Type trait for whether T is a std::tuple. More...
 
struct  gmx::test::detail::IsTuple< std::tuple< Ts...> >
 Specialization to successfully match a std::tuple. More...
 
class  gmx::test::NameOfTestFromTuple< ParametersTuple >
 Function object that helps GoogleTest name our test cases. More...
 
class  gmx::test::RefDataFilenameMaker< ParametersTuple >
 Functor to name a refdata filename for this test. More...
 
struct  gmx::test::PrefixFormatter< T, formatter >
 Functor to add a prefix to the return from formatter for T. More...
 

Functions

template<typename Param >
std::string gmx::test::detail::formatNameFromParam (const Param param, const typename FormatterVariant< Param >::Variant formatterVariant)
 Apply the formatterVariant to the respective param to produce a string. More...
 
template<typename T , T... S, typename F >
constexpr void gmx::test::detail::ForSequence (std::integer_sequence< T, S...>, F &&f)
 Fold a constexpr sequence of integers that match S to calls to the function f taking a matching std::integral_constant.
 
template<typename ParametersTuple >
std::string gmx::test::detail::mapNameFormattersToParameters (const ParametersTuple params, const typename ParamsToFormatterVariants< ParametersTuple >::type &formatters)
 Apply the formatters to the respective params to produce an underscore-separated string. More...
 
static std::string gmx::test::useString (const std::string s)
 Formatter to pass std::string through.
 
template<typename T >
std::string gmx::test::toEmptyString (const T)
 Formatter to ignore test parameters in a self-documenting way.
 

Variables

template<class >
constexpr bool gmx::test::detail::sc_alwaysFalse = false
 Helper constant for the std::visitor in formatNameFromParam. More...