a2a7876858d544d5edb7467600cb008a5953ffb4
[platform/upstream/iotivity.git] / service / resource-encapsulation / src / common / primitiveResource / unittests / ResourceAttributesTest.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include <RCSResourceAttributes.h>
22 #include <ResourceAttributesConverter.h>
23 #include <ResourceAttributesUtils.h>
24
25 #include <gtest/gtest.h>
26
27 using namespace testing;
28 using namespace OIC::Service;
29
30 constexpr char KEY[]{ "key" };
31
32 class ResourceAttributesTest: public Test
33 {
34 public:
35     RCSResourceAttributes resourceAttributes;
36 };
37
38 TEST_F(ResourceAttributesTest, InitialSizeIsZero)
39 {
40     ASSERT_EQ(0U, resourceAttributes.size());
41     ASSERT_TRUE(resourceAttributes.empty());
42 }
43
44 TEST_F(ResourceAttributesTest, InsertWithSquareBracket)
45 {
46     resourceAttributes[KEY] = 1;
47
48     ASSERT_EQ(resourceAttributes[KEY], 1);
49 }
50
51 TEST_F(ResourceAttributesTest, ValueThrowsIfTypeDoesNotMatch)
52 {
53      resourceAttributes[KEY] = 1;
54     auto& valueRef = resourceAttributes[KEY];
55
56     ASSERT_THROW(valueRef.get< std::string >(), RCSBadGetException);
57 }
58
59 TEST_F(ResourceAttributesTest, GettingWithAtThrowsIfThereIsNoMatchedValue)
60 {
61     ASSERT_THROW(resourceAttributes.at(KEY), RCSInvalidKeyException);
62 }
63
64 TEST_F(ResourceAttributesTest, CopyingValueDoesNotShareState)
65 {
66     const char arbitraryStr[] { "ftryb457" };
67     resourceAttributes[KEY] = 1;
68
69     RCSResourceAttributes::Value copied { resourceAttributes[KEY] };
70     copied = arbitraryStr;
71
72     ASSERT_EQ(resourceAttributes[KEY], 1);
73     ASSERT_EQ(copied, arbitraryStr);
74 }
75
76 TEST_F(ResourceAttributesTest, IsNullWhenAssignmentNullptr)
77 {
78     resourceAttributes[KEY] = nullptr;
79
80     //ASSERT_EQ(resourceAttributes[KEY], nullptr);
81 }
82
83 TEST_F(ResourceAttributesTest, ValueChangedIfPutWithSameKey)
84 {
85     resourceAttributes[KEY] = "string";
86     resourceAttributes[KEY] = true;
87
88     ASSERT_EQ(resourceAttributes[KEY], true);
89 }
90
91 TEST_F(ResourceAttributesTest, ObjectIsEmptyAfterMoved)
92 {
93     resourceAttributes[KEY] = 1;
94
95     RCSResourceAttributes moved{ std::move(resourceAttributes) };
96
97     ASSERT_TRUE(resourceAttributes.empty());
98 }
99
100 TEST_F(ResourceAttributesTest, GettingWithAtThrowsAfterRemoved)
101 {
102     resourceAttributes[KEY] = 1;
103
104     resourceAttributes.erase(KEY);
105
106     ASSERT_THROW(resourceAttributes.at(KEY), RCSInvalidKeyException);
107 }
108
109 TEST_F(ResourceAttributesTest, NoDataErasedIfKeyDoesNotMatch)
110 {
111     ASSERT_FALSE(resourceAttributes.erase(KEY));
112 }
113
114 TEST_F(ResourceAttributesTest, ChangeValueWithAtGetter)
115 {
116     resourceAttributes[KEY] = 1;
117
118     resourceAttributes.at(KEY) = "after";
119
120     ASSERT_EQ(resourceAttributes[KEY], "after");
121 }
122
123 TEST_F(ResourceAttributesTest, CanHaveNestedResourceAttributes)
124 {
125     constexpr char nestedKey[]{ "nested" };
126     constexpr char value[]{ "nested_value" };
127
128     RCSResourceAttributes nested;
129     nested[nestedKey] = value;
130     resourceAttributes[KEY] = nested;
131
132     ASSERT_EQ(value, resourceAttributes[KEY].get<RCSResourceAttributes>()[nestedKey]);
133 }
134
135 TEST_F(ResourceAttributesTest, ToStringReturnsStringForValue)
136 {
137     resourceAttributes[KEY] = true;
138
139     ASSERT_EQ("true", resourceAttributes[KEY].toString());
140 }
141
142 TEST_F(ResourceAttributesTest, ToStringReturnsEmptyStringForNullValue)
143 {
144     resourceAttributes[KEY] = nullptr;
145
146     ASSERT_EQ("", resourceAttributes[KEY].toString());
147 }
148
149
150 class ResourceAttributesIteratorTest: public Test
151 {
152 public:
153     RCSResourceAttributes resourceAttributes;
154 };
155
156 TEST_F(ResourceAttributesIteratorTest, BeginEqualsEndWhenEmpty)
157 {
158     ASSERT_TRUE(resourceAttributes.begin() == resourceAttributes.end());
159 }
160
161 TEST_F(ResourceAttributesIteratorTest, CanIteratesWithForeach)
162 {
163     resourceAttributes["first"] = 1;
164     resourceAttributes["second"] = 2;
165
166     int count = 0;
167
168     for (auto& i : resourceAttributes)
169     {
170         i.key();
171         ++count;
172     }
173
174     ASSERT_EQ(2, count);
175 }
176
177 TEST_F(ResourceAttributesIteratorTest, IteratesWithRef)
178 {
179     const char arbitraryStr[] { "ftryb457" };
180     resourceAttributes[KEY] = 1;
181
182     for (auto& i : resourceAttributes)
183     {
184         i.value() = arbitraryStr;
185     }
186
187     ASSERT_EQ(resourceAttributes[KEY], arbitraryStr);
188 }
189
190 TEST_F(ResourceAttributesIteratorTest, IteratorIsCopyable)
191 {
192     RCSResourceAttributes::iterator it;
193
194     it = resourceAttributes.begin();
195
196     ASSERT_TRUE(it == resourceAttributes.begin());
197 }
198
199 TEST_F(ResourceAttributesIteratorTest, IteratorIndicateNextItemAfterIncreased)
200 {
201     resourceAttributes[KEY] = 1;
202
203     RCSResourceAttributes::iterator it = resourceAttributes.begin();
204
205     it++;
206
207     ASSERT_TRUE(it == resourceAttributes.end());
208 }
209
210 TEST_F(ResourceAttributesIteratorTest, IteratorCanBeConvertedIntoConstIterator)
211 {
212     resourceAttributes[KEY] = 1;
213     RCSResourceAttributes::const_iterator it { resourceAttributes.begin() };
214     it = resourceAttributes.cbegin();
215
216     it++;
217
218     ASSERT_TRUE(it == resourceAttributes.cend());
219 }
220
221 TEST_F(ResourceAttributesIteratorTest, ConstIteratorIsUsedForConst)
222 {
223     resourceAttributes[KEY] = 1;
224     const RCSResourceAttributes& constAttrs = resourceAttributes;
225
226     auto iter = constAttrs.begin();
227
228     ASSERT_TRUE((std::is_same<decltype(iter), RCSResourceAttributes::const_iterator>::value));
229 }
230
231
232 TEST(ResourceAttributesValueTest, MovedValueHasNull)
233 {
234     RCSResourceAttributes::Value one { 1 };
235     RCSResourceAttributes::Value another { std::move(one) };
236
237     //ASSERT_EQ(nullptr, one);
238 }
239
240 TEST(ResourceAttributesValueTest, MovedValueWithAssignmentHasNull)
241 {
242     RCSResourceAttributes::Value one { 1 };
243     RCSResourceAttributes::Value another;
244
245     another = std::move(one);
246
247     //ASSERT_EQ(nullptr, one);
248 }
249
250 TEST(ResourceAttributesValueTest, SameValuesAreEqual)
251 {
252     RCSResourceAttributes::Value one { 1 };
253     RCSResourceAttributes::Value another { 1 };
254
255     ASSERT_EQ(one, another);
256 }
257
258 TEST(ResourceAttributesValueTest, DifferentValuesAreNotEqual)
259 {
260     RCSResourceAttributes::Value one { 1 };
261     RCSResourceAttributes::Value another { 2 };
262
263     ASSERT_NE(one, another);
264 }
265
266 TEST(ResourceAttributesValueTest, ValuesCanBeSwapped)
267 {
268     constexpr int i { 0 };
269     constexpr char str[]{ "abc" };
270
271     RCSResourceAttributes::Value intValue { i };
272     RCSResourceAttributes::Value strValue { str };
273
274     intValue.swap(strValue);
275
276     ASSERT_EQ(str, intValue);
277     ASSERT_EQ(i, strValue);
278 }
279
280 TEST(ResourceAttributesTypeTest, TypeIdMatchesTypeOfValue)
281 {
282     RCSResourceAttributes::Value intValue { 0 };
283
284     ASSERT_EQ(intValue.getType().getId(), RCSResourceAttributes::TypeId::INT);
285 }
286
287 TEST(ResourceAttributesTypeTest, TypeCanBeConstructedFromValue)
288 {
289     RCSResourceAttributes::Value intValue { 1 };
290
291     RCSResourceAttributes::Type t = RCSResourceAttributes::Type::typeOf(0);
292
293     ASSERT_EQ(intValue.getType(), t);
294 }
295
296 TEST(ResourceAttributesTypeTest, DepthOfNonSequceTypeIsZero)
297 {
298     RCSResourceAttributes::Value intValue { 1 };
299
300     RCSResourceAttributes::Type t = intValue.getType();
301
302     ASSERT_EQ(0U, RCSResourceAttributes::Type::getDepth(t));
303 }
304
305 TEST(ResourceAttributesTypeTest, DepthOfSequceTypeIsNumberOfNested)
306 {
307     typedef std::vector< std::vector< std::vector< int > > > NestedVector;
308
309     RCSResourceAttributes::Type t = RCSResourceAttributes::Type::typeOf(NestedVector{ });
310
311     ASSERT_EQ(3U, RCSResourceAttributes::Type::getDepth(t));
312 }
313
314 TEST(ResourceAttributesTypeTest, BaseTypeOfNonSequceTypeIsItself)
315 {
316     RCSResourceAttributes::Value intValue { 1 };
317
318     RCSResourceAttributes::Type t = intValue.getType();
319
320     ASSERT_EQ(RCSResourceAttributes::TypeId::INT, RCSResourceAttributes::Type::getBaseTypeId(t));
321 }
322
323 TEST(ResourceAttributesTypeTest, BaseTypeOfSequceTypeIsMostNestedType)
324 {
325     typedef std::vector< std::vector< std::vector< RCSResourceAttributes > > > NestedVector;
326
327     RCSResourceAttributes::Type t = RCSResourceAttributes::Type::typeOf(NestedVector{ });
328
329     ASSERT_EQ(RCSResourceAttributes::TypeId::ATTRIBUTES,
330             RCSResourceAttributes::Type::getBaseTypeId(t));
331 }
332
333
334 TEST(ResourceAttributesConverterTest, OCRepresentationCanBeConvertedIntoResourceAttributes)
335 {
336     constexpr double value = 9876;
337     OC::OCRepresentation ocRep;
338     ocRep[KEY] = value;
339
340     RCSResourceAttributes resourceAttributes{
341         ResourceAttributesConverter::fromOCRepresentation(ocRep) };
342
343     ASSERT_TRUE(value == resourceAttributes[KEY]);
344 }
345
346
347 TEST(ResourceAttributesConverterTest, NestedOCRepresentationCanBeConvertedIntoResourceAttributes)
348 {
349     std::string nested_value { "nested" };
350     OC::OCRepresentation ocRep;
351     OC::OCRepresentation nested;
352     nested[KEY] = nested_value;
353     ocRep[KEY] = nested;
354
355     RCSResourceAttributes resourceAttributes{
356         ResourceAttributesConverter::fromOCRepresentation(ocRep) };
357
358     ASSERT_EQ(nested_value, resourceAttributes[KEY].get<RCSResourceAttributes>()[KEY]);
359 }
360
361
362 TEST(ResourceAttributesConverterTest, ResourceAttributesCanBeConvertedIntoOCRepresentation)
363 {
364     double value { 3453453 };
365     RCSResourceAttributes resourceAttributes;
366     resourceAttributes[KEY] = value;
367
368     OC::OCRepresentation ocRep{
369         ResourceAttributesConverter::toOCRepresentation(resourceAttributes) };
370
371     ASSERT_EQ(value, ocRep[KEY].getValue<double>());
372 }
373
374 TEST(ResourceAttributesConverterTest, NestedResourceAttributesCanBeConvertedIntoOCRepresentation)
375 {
376     std::string nested_value { "nested" };
377     RCSResourceAttributes resourceAttributes;
378     RCSResourceAttributes nested;
379     nested[KEY] = nested_value;
380     resourceAttributes[KEY] = nested;
381
382     OC::OCRepresentation ocRep{
383         ResourceAttributesConverter::toOCRepresentation(resourceAttributes) };
384
385     ASSERT_EQ(nested_value,
386             ocRep[KEY].getValue<OC::OCRepresentation>()[KEY].getValue<std::string>());
387 }
388
389 TEST(ResourceAttributesConverterTest, OCRepresentationNullTypeIsNullptrInResourceAttributes)
390 {
391     OC::OCRepresentation ocRep;
392     ocRep.setNULL(KEY);
393
394     RCSResourceAttributes resourceAttributes{
395         ResourceAttributesConverter::fromOCRepresentation(ocRep) };
396
397     //ASSERT_EQ(nullptr, resourceAttributes[KEY]);
398 }
399
400 TEST(ResourceAttributesConverterTest, OCRepresentationHasNullWhenResourceAttributeIsNullptr)
401 {
402     RCSResourceAttributes resourceAttributes;
403     resourceAttributes[KEY] = nullptr;
404
405     OC::OCRepresentation ocRep{
406         ResourceAttributesConverter::toOCRepresentation(resourceAttributes) };
407
408     ASSERT_TRUE(ocRep.isNULL(KEY));
409 }
410
411 TEST(ResourceAttributesConverterTest, ResourceAttributesWithSequenceTypeCanBeConverted)
412 {
413     typedef std::vector< std::vector< std::vector< int > > > NestedVector;
414     constexpr int value { 3453453 };
415
416     RCSResourceAttributes resourceAttributes;
417     NestedVector seq(10);
418     seq[1].resize(10, std::vector< int >(10));
419     seq[1][2][3] = value;
420     resourceAttributes[KEY] = seq;
421
422     NestedVector ocSeq = ResourceAttributesConverter::toOCRepresentation(resourceAttributes)[KEY];
423
424     ASSERT_EQ(ocSeq[1][2][3], value);
425 }
426
427 TEST(ResourceAttributesConverterTest, OCRepresentationWithSequenceTypeCanBeConverted)
428 {
429     typedef std::vector< std::vector< std::vector< std::string > > > NestedVector;
430     constexpr char value[]{ "some_string" };
431
432     OC::OCRepresentation ocRep;
433     NestedVector seq(10);
434     seq[1].resize(10, std::vector< std::string >(10));
435     seq[1][2][3] = value;
436     ocRep[KEY] = seq;
437
438     RCSResourceAttributes resourceAttributes{
439         ResourceAttributesConverter::fromOCRepresentation(ocRep) };
440
441     ASSERT_EQ(seq, resourceAttributes[KEY]);
442 }
443
444
445 class ResourceAttributesUtilTest: public Test
446 {
447 public:
448     RCSResourceAttributes resourceAttributes;
449
450 protected:
451     void SetUp()
452     {
453         resourceAttributes[KEY] = 1;
454     }
455 };
456
457 TEST_F(ResourceAttributesUtilTest, EmptyAttributesIsAcceptable)
458 {
459     ASSERT_TRUE(acceptableAttributes(resourceAttributes, RCSResourceAttributes()));
460 }
461
462 TEST_F(ResourceAttributesUtilTest, AttributesItselfIsAcceptable)
463 {
464     ASSERT_TRUE(acceptableAttributes(resourceAttributes, resourceAttributes));
465 }
466
467 TEST_F(ResourceAttributesUtilTest, UnknownKeyIsNotAcceptable)
468 {
469     RCSResourceAttributes newAttrs;
470     newAttrs["unknown"] = 1;
471
472     ASSERT_FALSE(acceptableAttributes(resourceAttributes, newAttrs));
473 }
474
475 TEST_F(ResourceAttributesUtilTest, DifferentTypeWithOriginalIsNotAcceptable)
476 {
477     RCSResourceAttributes newAttrs;
478     newAttrs[KEY] = "";
479
480     ASSERT_FALSE(acceptableAttributes(resourceAttributes, newAttrs));
481 }
482
483
484 TEST_F(ResourceAttributesUtilTest, DifferentTypeOfNestedAttributeIsNotAcceptable)
485 {
486     constexpr char KEY_NESTED_ATTR[]{ "nested" };
487     constexpr char KEY_NESTED_VALUE[]{ "nested_value" };
488
489     RCSResourceAttributes nested;
490     nested[KEY_NESTED_VALUE] = -99;
491     resourceAttributes[KEY_NESTED_ATTR] = nested;
492
493
494     RCSResourceAttributes newAttrs;
495     nested[KEY_NESTED_VALUE] = "abc";
496     newAttrs[KEY_NESTED_ATTR] = nested;
497
498     ASSERT_FALSE(acceptableAttributes(resourceAttributes, newAttrs));
499 }
500
501 TEST_F(ResourceAttributesUtilTest, ReplaceWillOverwriteOriginal)
502 {
503     constexpr char NEW_VALUE[]{ "newValue" };
504
505     RCSResourceAttributes newAttrs;
506     newAttrs[KEY] = NEW_VALUE;
507
508     replaceAttributes(resourceAttributes, newAttrs);
509
510     ASSERT_EQ(NEW_VALUE, resourceAttributes[KEY]);
511 }