1 /*
2  * Copyright 2014 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #include <any>
19 #include <cstdint>
20 
21 #include <gtest/gtest.h>
22 
23 #include <ignition/math/Angle.hh>
24 
25 #include "sdf/Exception.hh"
26 #include "sdf/Param.hh"
27 
check_double(std::string num)28 bool check_double(std::string num)
29 {
30   const std::string name = "number";
31   const std::string type = "double";
32   const std::string def = "0.0";
33 
34   sdf::Param param(name, type, def, true);
35   return param.SetFromString(num);
36 }
37 
38 ////////////////////////////////////////////////////
39 /// Test getting a bool using true/false and 1/0.
TEST(Param,Bool)40 TEST(Param, Bool)
41 {
42   sdf::Param boolParam("key", "bool", "true", false, "description");
43   bool value = true;
44   boolParam.Get<bool>(value);
45   EXPECT_TRUE(value);
46 
47   boolParam.Set(false);
48   boolParam.Get<bool>(value);
49   EXPECT_FALSE(value);
50 
51   // String parameter that represents a boolean.
52   sdf::Param strParam("key", "string", "true", false, "description");
53 
54   strParam.Get<bool>(value);
55   EXPECT_TRUE(value);
56 
57   strParam.Set("false");
58   strParam.Get<bool>(value);
59   EXPECT_FALSE(value);
60 
61   strParam.Set("1");
62   strParam.Get<bool>(value);
63   EXPECT_TRUE(value);
64 
65   strParam.Set("0");
66   strParam.Get<bool>(value);
67   EXPECT_FALSE(value);
68 
69   strParam.Set("True");
70   strParam.Get<bool>(value);
71   EXPECT_TRUE(value);
72 
73   strParam.Set("TRUE");
74   strParam.Get<bool>(value);
75   EXPECT_TRUE(value);
76 
77   // Anything other than 1 or true is treated as a false value
78   strParam.Set("%");
79   strParam.Get<bool>(value);
80   EXPECT_FALSE(value);
81 
82   boolParam.Set(true);
83   std::any anyValue;
84   EXPECT_TRUE(boolParam.GetAny(anyValue));
85   try
86   {
87     value = std::any_cast<bool>(anyValue);
88   }
89   catch(std::bad_any_cast &/*_e*/)
90   {
91     FAIL();
92   }
93   EXPECT_TRUE(value);
94 }
95 
96 ////////////////////////////////////////////////////
97 /// Test decimal number
TEST(SetFromString,Decimals)98 TEST(SetFromString, Decimals)
99 {
100   ASSERT_TRUE(check_double("0.2345"));
101 }
102 
103 ////////////////////////////////////////////////////
104 /// Test setting and reading hex int values.
TEST(Param,HexInt)105 TEST(Param, HexInt)
106 {
107   sdf::Param intParam("key", "int", "0", false, "description");
108   int value;
109   EXPECT_TRUE(intParam.Get<int>(value));
110   EXPECT_EQ(value, 0);
111 
112   EXPECT_TRUE(intParam.SetFromString("0x01"));
113   EXPECT_TRUE(intParam.Get<int>(value));
114   EXPECT_EQ(value, 1);
115 
116   EXPECT_TRUE(intParam.SetFromString("0xff"));
117   EXPECT_TRUE(intParam.Get<int>(value));
118   EXPECT_EQ(value, 255);
119 
120   EXPECT_TRUE(intParam.SetFromString("0x00002"));
121   EXPECT_TRUE(intParam.Get<int>(value));
122   EXPECT_EQ(value, 2);
123 
124   EXPECT_FALSE(intParam.SetFromString("0xffffffffffffffffffffffffffffffffff"));
125   EXPECT_TRUE(intParam.Get<int>(value));
126   EXPECT_EQ(value, 2);
127 }
128 
129 ////////////////////////////////////////////////////
130 /// Test setting and reading hex unsigned int values.
TEST(Param,HexUInt)131 TEST(Param, HexUInt)
132 {
133   sdf::Param uintParam("key", "unsigned int", "0", false, "description");
134   unsigned int value;
135   EXPECT_TRUE(uintParam.Get<unsigned int>(value));
136   EXPECT_EQ(value, 0u);
137 
138   EXPECT_TRUE(uintParam.SetFromString("0x01"));
139   EXPECT_TRUE(uintParam.Get<unsigned int>(value));
140   EXPECT_EQ(value, 1u);
141 
142   EXPECT_TRUE(uintParam.SetFromString("0xff"));
143   EXPECT_TRUE(uintParam.Get<unsigned int>(value));
144   EXPECT_EQ(value, 255u);
145 
146   EXPECT_TRUE(uintParam.SetFromString("0x00002"));
147   EXPECT_TRUE(uintParam.Get<unsigned int>(value));
148   EXPECT_EQ(value, 2u);
149 
150   EXPECT_FALSE(uintParam.SetFromString("0xffffffffffffffffffffffffffffffffff"));
151   EXPECT_TRUE(uintParam.Get<unsigned int>(value));
152   EXPECT_EQ(value, 2u);
153 }
154 
155 ////////////////////////////////////////////////////
156 /// Test setting and reading hex and non-hex float values.
TEST(Param,HexFloat)157 TEST(Param, HexFloat)
158 {
159 // Microsoft does not parse hex values properly.
160 // https://bitbucket.org/osrf/sdformat/issues/114
161 #ifndef _MSC_VER
162   sdf::Param floatParam("key", "float", "0", false, "description");
163   float value;
164   EXPECT_TRUE(floatParam.Get<float>(value));
165   EXPECT_FLOAT_EQ(value, 0.0f);
166 
167   EXPECT_TRUE(floatParam.SetFromString("0x01"));
168   EXPECT_TRUE(floatParam.Get<float>(value));
169   EXPECT_FLOAT_EQ(value, 1.0f);
170 
171   EXPECT_TRUE(floatParam.SetFromString("0X2A"));
172   EXPECT_TRUE(floatParam.Get<float>(value));
173   EXPECT_FLOAT_EQ(value, 42.0f);
174 
175   EXPECT_TRUE(floatParam.SetFromString("0.123"));
176   EXPECT_TRUE(floatParam.Get<float>(value));
177   EXPECT_FLOAT_EQ(value, 0.123f);
178 
179   EXPECT_FALSE(floatParam.SetFromString("1.0e100"));
180   EXPECT_TRUE(floatParam.Get<float>(value));
181   EXPECT_FLOAT_EQ(value, 0.123f);
182 #endif
183 }
184 
185 ////////////////////////////////////////////////////
186 /// Test setting and reading hex and non-hex double values.
TEST(Param,HexDouble)187 TEST(Param, HexDouble)
188 {
189   sdf::Param doubleParam("key", "double", "0", false, "description");
190   double value;
191   EXPECT_TRUE(doubleParam.Get<double>(value));
192   EXPECT_DOUBLE_EQ(value, 0.0);
193 
194 // Microsoft does not parse hex values properly.
195 // https://bitbucket.org/osrf/sdformat/issues/114
196 #ifndef _MSC_VER
197   EXPECT_TRUE(doubleParam.SetFromString("0x01"));
198   EXPECT_TRUE(doubleParam.Get<double>(value));
199   EXPECT_DOUBLE_EQ(value, 1.0);
200 
201   EXPECT_TRUE(doubleParam.SetFromString("0X2A"));
202   EXPECT_TRUE(doubleParam.Get<double>(value));
203   EXPECT_DOUBLE_EQ(value, 42.0);
204 #endif
205   EXPECT_TRUE(doubleParam.SetFromString("0.123456789"));
206   EXPECT_TRUE(doubleParam.Get<double>(value));
207   EXPECT_DOUBLE_EQ(value, 0.123456789);
208 
209   EXPECT_FALSE(doubleParam.SetFromString("1.0e1000"));
210   EXPECT_TRUE(doubleParam.Get<double>(value));
211   EXPECT_DOUBLE_EQ(value, 0.123456789);
212 }
213 
214 ////////////////////////////////////////////////////
215 /// Test setting and reading uint64_t values.
TEST(Param,uint64t)216 TEST(Param, uint64t)
217 {
218   sdf::Param uint64tParam("key", "uint64_t", "1", false, "description");
219   std::uint64_t value;
220   EXPECT_TRUE(uint64tParam.Get<std::uint64_t>(value));
221   EXPECT_EQ(value, 1u);
222 
223   // Max uint64_t
224   EXPECT_TRUE(uint64tParam.SetFromString("18446744073709551615"));
225   EXPECT_TRUE(uint64tParam.Get<std::uint64_t>(value));
226   EXPECT_EQ(value, UINT64_MAX);
227 }
228 
229 ////////////////////////////////////////////////////
230 /// Unknown type, should fall back to stream operators
TEST(Param,UnknownType)231 TEST(Param, UnknownType)
232 {
233   sdf::Param doubleParam("key", "double", "1.0", false, "description");
234   ignition::math::Angle value;
235   EXPECT_TRUE(doubleParam.Get<ignition::math::Angle>(value));
236   EXPECT_DOUBLE_EQ(value.Radian(), 1.0);
237 }
238 
239 ////////////////////////////////////////////////////
TEST(Param,Vector2i)240 TEST(Param, Vector2i)
241 {
242   sdf::Param vect2iParam("key", "vector2i", "0 0", false, "description");
243   ignition::math::Vector2i value;
244 
245   EXPECT_TRUE(vect2iParam.Get<ignition::math::Vector2i>(value));
246   EXPECT_EQ(value, ignition::math::Vector2i(0, 0));
247 }
248 
249 ////////////////////////////////////////////////////
TEST(Param,InvalidConstructor)250 TEST(Param, InvalidConstructor)
251 {
252   ASSERT_THROW(sdf::Param badParam("key", "badtype", "0", false, "description"),
253                sdf::AssertionInternalError);
254 }
255 
256 ////////////////////////////////////////////////////
TEST(Param,SetDescription)257 TEST(Param, SetDescription)
258 {
259   sdf::Param uint64Param("key", "uint64_t", "1", false, "description");
260 
261   uint64Param.SetDescription("new desc");
262 
263   ASSERT_EQ("new desc", uint64Param.GetDescription());
264 }
265 
266 ////////////////////////////////////////////////////
TEST(Param,Reset)267 TEST(Param, Reset)
268 {
269   sdf::Param uint64Param("key", "uint64_t", "1", false, "description");
270   uint64_t val;
271 
272   uint64Param.SetFromString("89");
273 
274   uint64Param.Get<uint64_t>(val);
275   ASSERT_EQ(89UL, val);
276 
277   uint64Param.Reset();
278 
279   uint64Param.Get<uint64_t>(val);
280   ASSERT_EQ(1UL, val);
281 }
282 
283 ////////////////////////////////////////////////////
TEST(Param,EmptyRequiredSetFromString)284 TEST(Param, EmptyRequiredSetFromString)
285 {
286   sdf::Param uint64Param("key", "uint64_t", "1", true, "description");
287   uint64_t val;
288 
289   ASSERT_FALSE(uint64Param.SetFromString(""));
290   uint64Param.Get<uint64_t>(val);
291 
292   ASSERT_EQ(1UL, val);
293 }
294 
295 ////////////////////////////////////////////////////
TEST(Param,EmptySetFromString)296 TEST(Param, EmptySetFromString)
297 {
298   sdf::Param uint64Param("key", "uint64_t", "1", false, "description");
299 
300   uint64_t val;
301 
302   uint64Param.SetFromString("89");
303 
304   ASSERT_TRUE(uint64Param.SetFromString(""));
305   uint64Param.Get<uint64_t>(val);
306 
307   ASSERT_EQ(1UL, val);
308 }
309 
310 ////////////////////////////////////////////////////
TEST(Param,InvalidBool)311 TEST(Param, InvalidBool)
312 {
313   sdf::Param boolParam("key", "bool", "true", false, "description");
314 
315   ASSERT_FALSE(boolParam.SetFromString("false1"));
316 }
317 
318 ////////////////////////////////////////////////////
TEST(Param,InvalidInt)319 TEST(Param, InvalidInt)
320 {
321   sdf::Param intParam("key", "int", "1", false, "description");
322 
323   ASSERT_FALSE(intParam.SetFromString("abc"));
324 }
325 
326 ////////////////////////////////////////////////////
TEST(Param,GetAny)327 TEST(Param, GetAny)
328 {
329   std::any anyValue;
330 
331   sdf::Param intParam("key", "int", "true", false, "description");
332   EXPECT_TRUE(intParam.GetAny(anyValue));
333 
334   sdf::Param uint64Param("key", "uint64_t", "1", false, "description");
335   EXPECT_TRUE(uint64Param.GetAny(anyValue));
336 
337   sdf::Param doubleParam("key", "double", "1.0", false, "description");
338   EXPECT_TRUE(doubleParam.GetAny(anyValue));
339 
340   sdf::Param floatParam("key", "float", "1.0", false, "description");
341   EXPECT_TRUE(floatParam.GetAny(anyValue));
342 
343   sdf::Param boolParam("key", "bool", "true", false, "description");
344   EXPECT_TRUE(boolParam.GetAny(anyValue));
345 
346   sdf::Param stringParam("key", "string", "hello", false, "description");
347   EXPECT_TRUE(stringParam.GetAny(anyValue));
348 
349   sdf::Param unsignedParam("key", "unsigned int", "1", false, "description");
350   EXPECT_TRUE(unsignedParam.GetAny(anyValue));
351 
352   sdf::Param charParam("key", "char", "a", false, "description");
353   EXPECT_TRUE(charParam.GetAny(anyValue));
354 
355   sdf::Param timeParam("key", "time", "8 20", false, "description");
356   EXPECT_TRUE(timeParam.GetAny(anyValue));
357 
358   sdf::Param colorParam("key", "color", "8 20 67 23", false, "description");
359   EXPECT_TRUE(colorParam.GetAny(anyValue));
360 
361   sdf::Param vector3Param("key", "vector3", "8.1 20.24 67.7", false,
362                           "description");
363   EXPECT_TRUE(vector3Param.GetAny(anyValue));
364 
365   sdf::Param vector2iParam("key", "vector2i", "8 20", false, "description");
366   EXPECT_TRUE(vector2iParam.GetAny(anyValue));
367 
368   sdf::Param vector2dParam("key", "vector2d", "8.1 20.24", false,
369                            "description");
370   EXPECT_TRUE(vector2dParam.GetAny(anyValue));
371 
372   sdf::Param poseParam("key", "pose", "1 2 3 4 5 6", false, "description");
373   EXPECT_TRUE(poseParam.GetAny(anyValue));
374 
375   sdf::Param quatParam("key", "quaternion", "1 2 3 4", false, "description");
376   EXPECT_TRUE(quatParam.GetAny(anyValue));
377 }
378 
379 ////////////////////////////////////////////////////
TEST(Param,SetTemplate)380 TEST(Param, SetTemplate)
381 {
382   sdf::Param doubleParam("key", "double", "1.0", false, "description");
383   double value;
384 
385   EXPECT_TRUE(doubleParam.Get<double>(value));
386   EXPECT_DOUBLE_EQ(value, 1.0);
387 
388   doubleParam.Set<double>(25.456);
389 
390   EXPECT_TRUE(doubleParam.Get<double>(value));
391   EXPECT_DOUBLE_EQ(value, 25.456);
392 }
393 
394 /////////////////////////////////////////////////
395 /// Main
main(int argc,char ** argv)396 int main(int argc, char **argv)
397 {
398   ::testing::InitGoogleTest(&argc, argv);
399   return RUN_ALL_TESTS();
400 }
401