1 /**
2  * (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
3  * (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
4  *
5  * @file TypeTraits_test.cpp
6  *
7  * Created on: Nov 27, 2016
8  * Project: sdbus-c++
9  * Description: High-level D-Bus IPC C++ library based on sd-bus
10  *
11  * This file is part of sdbus-c++.
12  *
13  * sdbus-c++ is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU Lesser General Public License as published by
15  * the Free Software Foundation, either version 2.1 of the License, or
16  * (at your option) any later version.
17  *
18  * sdbus-c++ is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License
24  * along with sdbus-c++. If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 #include <sdbus-c++/TypeTraits.h>
28 #include <sdbus-c++/Types.h>
29 #include <gtest/gtest.h>
30 #include <gmock/gmock.h>
31 #include <cstdint>
32 #include <type_traits>
33 
34 using ::testing::Eq;
35 
36 namespace
37 {
38     // ---
39     // FIXTURE DEFINITION FOR TYPED TESTS
40     // ----
41 
42     template <typename _T>
43     class Type2DBusTypeSignatureConversion
44         : public ::testing::Test
45     {
46     protected:
47         const std::string dbusTypeSignature_{getDBusTypeSignature()};
48     private:
49         static std::string getDBusTypeSignature();
50     };
51 
52 #define TYPE(...)                                                                       \
53     template <>                                                                         \
54     std::string Type2DBusTypeSignatureConversion<__VA_ARGS__>::getDBusTypeSignature()   \
55     /**/
56 #define HAS_DBUS_TYPE_SIGNATURE(_SIG)                                                   \
57     {                                                                                   \
58         return (_SIG);                                                                  \
59     }                                                                                   \
60     /**/
61 
62     TYPE(bool)HAS_DBUS_TYPE_SIGNATURE("b")
63     TYPE(uint8_t)HAS_DBUS_TYPE_SIGNATURE("y")
64     TYPE(int16_t)HAS_DBUS_TYPE_SIGNATURE("n")
65     TYPE(uint16_t)HAS_DBUS_TYPE_SIGNATURE("q")
66     TYPE(int32_t)HAS_DBUS_TYPE_SIGNATURE("i")
67     TYPE(uint32_t)HAS_DBUS_TYPE_SIGNATURE("u")
68     TYPE(int64_t)HAS_DBUS_TYPE_SIGNATURE("x")
69     TYPE(uint64_t)HAS_DBUS_TYPE_SIGNATURE("t")
70     TYPE(double)HAS_DBUS_TYPE_SIGNATURE("d")
71     TYPE(const char*)HAS_DBUS_TYPE_SIGNATURE("s")
72     TYPE(std::string)HAS_DBUS_TYPE_SIGNATURE("s")
73     TYPE(sdbus::ObjectPath)HAS_DBUS_TYPE_SIGNATURE("o")
74     TYPE(sdbus::Signature)HAS_DBUS_TYPE_SIGNATURE("g")
75     TYPE(sdbus::Variant)HAS_DBUS_TYPE_SIGNATURE("v")
76     TYPE(sdbus::UnixFd)HAS_DBUS_TYPE_SIGNATURE("h")
77     TYPE(sdbus::Struct<bool>)HAS_DBUS_TYPE_SIGNATURE("(b)")
78     TYPE(sdbus::Struct<uint16_t, double, std::string, sdbus::Variant>)HAS_DBUS_TYPE_SIGNATURE("(qdsv)")
79     TYPE(std::vector<int16_t>)HAS_DBUS_TYPE_SIGNATURE("an")
80     TYPE(std::map<int32_t, int64_t>)HAS_DBUS_TYPE_SIGNATURE("a{ix}")
81     using ComplexType = std::map<
82                             uint64_t,
83                             sdbus::Struct<
84                                 std::map<
85                                     uint8_t,
86                                     std::vector<
87                                         sdbus::Struct<
88                                             sdbus::ObjectPath,
89                                             bool,
90                                             sdbus::Variant,
91                                             std::map<int, std::string>
92                                         >
93                                     >
94                                 >,
95                                 sdbus::Signature,
96                                 sdbus::UnixFd,
97                                 const char*
98                             >
99                         >;
100     TYPE(ComplexType)HAS_DBUS_TYPE_SIGNATURE("a{t(a{ya(obva{is})}ghs)}")
101 
102     typedef ::testing::Types< bool
103                             , uint8_t
104                             , int16_t
105                             , uint16_t
106                             , int32_t
107                             , uint32_t
108                             , int64_t
109                             , uint64_t
110                             , double
111                             , const char*
112                             , std::string
113                             , sdbus::ObjectPath
114                             , sdbus::Signature
115                             , sdbus::Variant
116                             , sdbus::UnixFd
117                             , sdbus::Struct<bool>
118                             , sdbus::Struct<uint16_t, double, std::string, sdbus::Variant>
119                             , std::vector<int16_t>
120                             , std::map<int32_t, int64_t>
121                             , ComplexType
122                             > DBusSupportedTypes;
123 
124     TYPED_TEST_SUITE(Type2DBusTypeSignatureConversion, DBusSupportedTypes);
125 }
126 
127 /*-------------------------------------*/
128 /* --          TEST CASES           -- */
129 /*-------------------------------------*/
130 
TYPED_TEST(Type2DBusTypeSignatureConversion,ConvertsTypeToProperDBusSignature)131 TYPED_TEST(Type2DBusTypeSignatureConversion, ConvertsTypeToProperDBusSignature)
132 {
133     ASSERT_THAT(sdbus::signature_of<TypeParam>::str(), Eq(this->dbusTypeSignature_));
134 }
135 
TEST(FreeFunctionTypeTraits,DetectsTraitsOfTrivialSignatureFunction)136 TEST(FreeFunctionTypeTraits, DetectsTraitsOfTrivialSignatureFunction)
137 {
138     void f();
139     using Fnc = decltype(f);
140 
141     static_assert(!sdbus::is_async_method_v<Fnc>, "Free function incorrectly detected as async method");
142     static_assert(std::is_same<sdbus::function_arguments_t<Fnc>, std::tuple<>>::value, "Incorrectly detected free function parameters");
143     static_assert(std::is_same<sdbus::tuple_of_function_input_arg_types_t<Fnc>, std::tuple<>>::value, "Incorrectly detected tuple of free function parameters");
144     static_assert(std::is_same<sdbus::tuple_of_function_output_arg_types_t<Fnc>, void>::value, "Incorrectly detected tuple of free function return types");
145     static_assert(sdbus::function_argument_count_v<Fnc> == 0, "Incorrectly detected free function parameter count");
146     static_assert(std::is_void<sdbus::function_result_t<Fnc>>::value, "Incorrectly detected free function return type");
147 }
148 
TEST(FreeFunctionTypeTraits,DetectsTraitsOfNontrivialSignatureFunction)149 TEST(FreeFunctionTypeTraits, DetectsTraitsOfNontrivialSignatureFunction)
150 {
151     std::tuple<char, int> f(double&, const char*, int);
152     using Fnc = decltype(f);
153 
154     static_assert(!sdbus::is_async_method_v<Fnc>, "Free function incorrectly detected as async method");
155     static_assert(std::is_same<sdbus::function_arguments_t<Fnc>, std::tuple<double&, const char*, int>>::value, "Incorrectly detected free function parameters");
156     static_assert(std::is_same<sdbus::tuple_of_function_input_arg_types_t<Fnc>, std::tuple<double, const char*, int>>::value, "Incorrectly detected tuple of free function parameters");
157     static_assert(std::is_same<sdbus::tuple_of_function_output_arg_types_t<Fnc>, std::tuple<char, int>>::value, "Incorrectly detected tuple of free function return types");
158     static_assert(sdbus::function_argument_count_v<Fnc> == 3, "Incorrectly detected free function parameter count");
159     static_assert(std::is_same<sdbus::function_result_t<Fnc>, std::tuple<char, int>>::value, "Incorrectly detected free function return type");
160 }
161 
TEST(FreeFunctionTypeTraits,DetectsTraitsOfAsyncFunction)162 TEST(FreeFunctionTypeTraits, DetectsTraitsOfAsyncFunction)
163 {
164     void f(sdbus::Result<char, int>, double&, const char*, int);
165     using Fnc = decltype(f);
166 
167     static_assert(sdbus::is_async_method_v<Fnc>, "Free async function incorrectly detected as sync method");
168     static_assert(std::is_same<sdbus::function_arguments_t<Fnc>, std::tuple<double&, const char*, int>>::value, "Incorrectly detected free function parameters");
169     static_assert(std::is_same<sdbus::tuple_of_function_input_arg_types_t<Fnc>, std::tuple<double, const char*, int>>::value, "Incorrectly detected tuple of free function parameters");
170     static_assert(std::is_same<sdbus::tuple_of_function_output_arg_types_t<Fnc>, std::tuple<char, int>>::value, "Incorrectly detected tuple of free function return types");
171     static_assert(sdbus::function_argument_count_v<Fnc> == 3, "Incorrectly detected free function parameter count");
172     static_assert(std::is_same<sdbus::function_result_t<Fnc>, std::tuple<char, int>>::value, "Incorrectly detected free function return type");
173 }
174