[test] Test cases parametrized by both type and value?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[test] Test cases parametrized by both type and value?

Boost - Dev mailing list
Hi,
Can anyone tell me if Boost.Test can solve the problem that I describe
below.

I have a function template inspect:

```
template <typename T>
bool inspect(T const& v);
```

I want to test if it returns `true` for the following values:

    1 (type int)
    10 (type int)
    1.0 (type double)
    "Y" (type const char *)

Basically, different values of different types, but sometimes different
values have the same type. I would like to write one test or "test
template" with the following contents:

```
BOOST_TEST((inspect(v)));
```

Where `v` is name of the currently tested value. (But `v`s will have
different types). I can emulate this behavior using template test cases and
artificial types:

```
struct int_1 {
  static int value() { return 1; }
};
struct int_10 {
  static int value() { return 10; }
};
struct double_1 {
  static double value() { return 1.0; }
};
struct cstr_Y {
  static const char * value() { return "Y"; }
};

typedef boost::mpl::list<int_1, int_10, double_1, cstr_Y> test_types;

BOOST_AUTO_TEST_CASE_TEMPLATE( my_test, T, test_types )
{
  BOOST_TEST(inspect(T::value()));
}
```

(See working example in WandBox:
https://wandbox.org/permlink/KcJqT8KvL3zIqAxL)

But maybe there exists a direct solution in Boost.Test? Where I would just
pass a list of values: `{1, 10, 1.0, "Y"}`

It is easy to deduce types from values:

```
template <typename... T>
mpl::liss<T...> Values(T... values);

using test_types = decltype(Values(1, 10, 1.0, "Y"));
```

Does something like this exist, or ois it a reasonable extension?

Regards,
&rzej;

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [test] Test cases parametrized by both type and value?

Boost - Dev mailing list
AMDG

On 01/05/2018 04:39 AM, Andrzej Krzemienski via Boost wrote:

> <snip>
> But maybe there exists a direct solution in Boost.Test? Where I would just
> pass a list of values: `{1, 10, 1.0, "Y"}`
>
> It is easy to deduce types from values:
>
> ```
> template <typename... T>
> mpl::liss<T...> Values(T... values);
>
> using test_types = decltype(Values(1, 10, 1.0, "Y"));
> ```
>
> Does something like this exist, or ois it a reasonable extension?
>
It isn't supported, but seems to be intended at some point:

http://www.boost.org/libs/test/doc/html/boost_test/tests_organization/test_cases/test_case_generation/datasets.html#ftn.boost_test.tests_organization.test_cases.test_case_generation.datasets.f0

In Christ,
Steven Watanabe

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [test] Test cases parametrized by both type and value?

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
On 1/5/18 3:39 AM, Andrzej Krzemienski via Boost wrote:

> Hi,
> Can anyone tell me if Boost.Test can solve the problem that I describe
> below.
>
> I have a function template inspect:
>
> ```
> template <typename T>
> bool inspect(T const& v);
> ```
>
> I want to test if it returns `true` for the following values:
>
>      1 (type int)
>      10 (type int)
>      1.0 (type double)
>      "Y" (type const char *)
>
> Basically, different values of different types, but sometimes different
> values have the same type. I would like to write one test or "test
> template" with the following contents:
>
> ```
> BOOST_TEST((inspect(v)));
> ```
>
> Where `v` is name of the currently tested value. (But `v`s will have
> different types). I can emulate this behavior using template test cases and
> artificial types:
>
> ```
> struct int_1 {
>    static int value() { return 1; }
> };
> struct int_10 {
>    static int value() { return 10; }
> };
> struct double_1 {
>    static double value() { return 1.0; }
> };
> struct cstr_Y {
>    static const char * value() { return "Y"; }
> };
>
> typedef boost::mpl::list<int_1, int_10, double_1, cstr_Y> test_types;
>
> BOOST_AUTO_TEST_CASE_TEMPLATE( my_test, T, test_types )
> {
>    BOOST_TEST(inspect(T::value()));
> }
> ```
>
> (See working example in WandBox:
> https://wandbox.org/permlink/KcJqT8KvL3zIqAxL)
>
> But maybe there exists a direct solution in Boost.Test? Where I would just
> pass a list of values: `{1, 10, 1.0, "Y"}`
>
> It is easy to deduce types from values:
>
> ```
> template <typename... T>
> mpl::liss<T...> Values(T... values);
>
> using test_types = decltype(Values(1, 10, 1.0, "Y"));
> ```
>
> Does something like this exist, or ois it a reasonable extension?
>
> Regards,
> &rzej;
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>


I've handled this a number of ways.  My latest favorite is

struct t {
     static bool m_error;
     template<typename T>
     void operator()(const T &){        std::cout
             << "** testing "
             << boost::core::demangle(typeid(T).name())
             << std::endl;
         m_error &=
             std::numeric_limits<T>::is_signed
             ? test_pairs(signed_value<T>, signed_multiplication_results)
             : test_pairs(unsigned_value<T>,
unsigned_multiplication_results)
         ;
     }
};
bool t::m_error = true;

bool test_all_types(){
     t rval;
     boost::mp11::mp_for_each<
         boost::mp11::mp_list<
             std::int8_t, std::int16_t, std::int32_t, std::int64_t,
             std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t
         >
     >(rval);
     return rval.m_error; // maybe call BOOST_TEST macro here.
}

I've also used boost preprocessor to do something similar.  It's hard to
post here as it's spread across various header flles.  You can see how
this is used by checking out the code in the current safe numerics
implementation.

I don't use boost test, but I don't seen how things would change much if
I did.

Robert Ramey

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [test] Test cases parametrized by both type and value?

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
Le 05.01.18 à 12:39, Andrzej Krzemienski via Boost a écrit :

> Hi,
> Can anyone tell me if Boost.Test can solve the problem that I describe
> below.
>
> I have a function template inspect:
>
> ```
> template <typename T>
> bool inspect(T const& v);
> ```
>
> I want to test if it returns `true` for the following values:
>
>     1 (type int)
>     10 (type int)
>     1.0 (type double)
>     "Y" (type const char *)
>
> Basically, different values of different types, but sometimes different
> values have the same type. I would like to write one test or "test
> template" with the following contents:
>
> ```
> BOOST_TEST((inspect(v)));
> ```
>
> Where `v` is name of the currently tested value. (But `v`s will have
> different types). I can emulate this behavior using template test cases and
> artificial types:
>
> ```
> struct int_1 {
>   static int value() { return 1; }
> };
> struct int_10 {
>   static int value() { return 10; }
> };
> struct double_1 {
>   static double value() { return 1.0; }
> };
> struct cstr_Y {
>   static const char * value() { return "Y"; }
> };
>
> typedef boost::mpl::list<int_1, int_10, double_1, cstr_Y> test_types;
>
> BOOST_AUTO_TEST_CASE_TEMPLATE( my_test, T, test_types )
> {
>   BOOST_TEST(inspect(T::value()));
> }
> ```
>
> (See working example in WandBox:
> https://wandbox.org/permlink/KcJqT8KvL3zIqAxL)
>
> But maybe there exists a direct solution in Boost.Test? Where I would just
> pass a list of values: `{1, 10, 1.0, "Y"}`
>
> It is easy to deduce types from values:
>
> ```
> template <typename... T>
> mpl::liss<T...> Values(T... values);
>
> using test_types = decltype(Values(1, 10, 1.0, "Y"));
> ```
>
> Does something like this exist, or ois it a reasonable extension?

As Steven said, it was considered during the initial developments from
Gennadiy but nobody expressed the need, so we did not go further that
direction.

I recently extended the inference of the types from
BOOST_AUTO_TEST_CASE_TEMPLATE to consider tuples instead of an mpl::list
(trac https://svn.boost.org/trac10/ticket/12092) but this is only
considering types. Adding the value carried by the tuple should not be
too difficult, and I think would address your feature request.

OTOH, providing an compile time iterator interface to datasets for
polymorphic collections is a nice feature. Will consider it again :) but
there are other things I would like to push forward first.

Raffi





_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost