blob: 955a19b81044df4b606d6564b5d1503a9cb97449 [file] [log] [blame]
Kim Paulhamus6efcf4952017-09-14 22:46:271// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Jun Choi9f1446c02017-12-21 23:33:275#include "components/cbor/cbor_writer.h"
Kim Paulhamus6efcf4952017-09-14 22:46:276
Jun Choi06ae32d2017-12-21 18:52:397#include <limits>
Jun Choi0ca86672017-11-14 04:58:248#include <string>
9
Kim Paulhamus6efcf4952017-09-14 22:46:2710#include "testing/gmock/include/gmock/gmock.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13/* Leveraging RFC 7049 examples from
14 https://github.com/cbor/test-vectors/blob/master/appendix_a.json. */
Jun Choi9f1446c02017-12-21 23:33:2715namespace cbor {
Kim Paulhamus6efcf4952017-09-14 22:46:2716
17TEST(CBORWriterTest, TestWriteUint) {
18 typedef struct {
Jun Choi06ae32d2017-12-21 18:52:3919 const int64_t value;
Kim Paulhamus6efcf4952017-09-14 22:46:2720 const base::StringPiece cbor;
21 } UintTestCase;
22
23 static const UintTestCase kUintTestCases[] = {
24 // Reminder: must specify length when creating string pieces
25 // with null bytes, else the string will truncate prematurely.
26 {0, base::StringPiece("\x00", 1)},
27 {1, base::StringPiece("\x01")},
28 {10, base::StringPiece("\x0a")},
29 {23, base::StringPiece("\x17")},
30 {24, base::StringPiece("\x18\x18")},
31 {25, base::StringPiece("\x18\x19")},
32 {100, base::StringPiece("\x18\x64")},
33 {1000, base::StringPiece("\x19\x03\xe8")},
34 {1000000, base::StringPiece("\x1a\x00\x0f\x42\x40", 5)},
35 {0xFFFFFFFF, base::StringPiece("\x1a\xff\xff\xff\xff")},
Jun Choi06ae32d2017-12-21 18:52:3936 {0x100000000,
37 base::StringPiece("\x1b\x00\x00\x00\x01\x00\x00\x00\x00", 9)},
38 {std::numeric_limits<int64_t>::max(),
39 base::StringPiece("\x1b\x7f\xff\xff\xff\xff\xff\xff\xff")}};
Kim Paulhamus6efcf4952017-09-14 22:46:2740
41 for (const UintTestCase& test_case : kUintTestCases) {
Jun Choi0ca86672017-11-14 04:58:2442 auto cbor = CBORWriter::Write(CBORValue(test_case.value));
43 ASSERT_TRUE(cbor.has_value());
44 EXPECT_THAT(cbor.value(), testing::ElementsAreArray(test_case.cbor));
Kim Paulhamus6efcf4952017-09-14 22:46:2745 }
46}
47
Jun Choi06ae32d2017-12-21 18:52:3948TEST(CBORWriterTest, TestWriteNegativeInteger) {
49 static const struct {
50 const int64_t negative_int;
51 const base::StringPiece cbor;
52 } kNegativeIntTestCases[] = {
53 {-1LL, base::StringPiece("\x20")},
54 {-10LL, base::StringPiece("\x29")},
55 {-23LL, base::StringPiece("\x36")},
56 {-24LL, base::StringPiece("\x37")},
57 {-25LL, base::StringPiece("\x38\x18")},
58 {-100LL, base::StringPiece("\x38\x63")},
59 {-1000LL, base::StringPiece("\x39\x03\xe7")},
60 {-4294967296LL, base::StringPiece("\x3a\xff\xff\xff\xff")},
61 {-4294967297LL,
62 base::StringPiece("\x3b\x00\x00\x00\x01\x00\x00\x00\x00", 9)},
63 {std::numeric_limits<int64_t>::min(),
64 base::StringPiece("\x3b\x7f\xff\xff\xff\xff\xff\xff\xff")},
65 };
66
67 for (const auto& test_case : kNegativeIntTestCases) {
68 SCOPED_TRACE(testing::Message() << "testing negative int at index: "
69 << test_case.negative_int);
70
71 auto cbor = CBORWriter::Write(CBORValue(test_case.negative_int));
72 ASSERT_TRUE(cbor.has_value());
73 EXPECT_THAT(cbor.value(), testing::ElementsAreArray(test_case.cbor));
74 }
75}
76
Kim Paulhamus6efcf4952017-09-14 22:46:2777TEST(CBORWriterTest, TestWriteBytes) {
78 typedef struct {
79 const std::vector<uint8_t> bytes;
80 const base::StringPiece cbor;
81 } BytesTestCase;
82
83 static const BytesTestCase kBytesTestCases[] = {
84 {{}, base::StringPiece("\x40")},
85 {{0x01, 0x02, 0x03, 0x04}, base::StringPiece("\x44\x01\x02\x03\x04")},
86 };
87
88 for (const BytesTestCase& test_case : kBytesTestCases) {
Jun Choi0ca86672017-11-14 04:58:2489 auto cbor = CBORWriter::Write(CBORValue(test_case.bytes));
90 ASSERT_TRUE(cbor.has_value());
91 EXPECT_THAT(cbor.value(), testing::ElementsAreArray(test_case.cbor));
Kim Paulhamus6efcf4952017-09-14 22:46:2792 }
93}
94
95TEST(CBORWriterTest, TestWriteString) {
96 typedef struct {
97 const std::string string;
98 const base::StringPiece cbor;
99 } StringTestCase;
100
101 static const StringTestCase kStringTestCases[] = {
102 {"", base::StringPiece("\x60")},
103 {"a", base::StringPiece("\x61\x61")},
104 {"IETF", base::StringPiece("\x64\x49\x45\x54\x46")},
105 {"\"\\", base::StringPiece("\x62\x22\x5c")},
106 {"\xc3\xbc", base::StringPiece("\x62\xc3\xbc")},
107 {"\xe6\xb0\xb4", base::StringPiece("\x63\xe6\xb0\xb4")},
108 {"\xf0\x90\x85\x91", base::StringPiece("\x64\xf0\x90\x85\x91")}};
109
110 for (const StringTestCase& test_case : kStringTestCases) {
Jun Choi06ae32d2017-12-21 18:52:39111 SCOPED_TRACE(testing::Message()
112 << "testing encoding string : " << test_case.string);
113
Jun Choi0ca86672017-11-14 04:58:24114 auto cbor = CBORWriter::Write(CBORValue(test_case.string));
115 ASSERT_TRUE(cbor.has_value());
116 EXPECT_THAT(cbor.value(), testing::ElementsAreArray(test_case.cbor));
Kim Paulhamus6efcf4952017-09-14 22:46:27117 }
118}
119
120TEST(CBORWriterTest, TestWriteArray) {
121 static const uint8_t kArrayTestCaseCbor[] = {
Adam Langley68672fd2017-10-17 19:35:27122 // clang-format off
123 0x98, 0x19, // array of 25 elements
124 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
125 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
126 0x18, 0x18, 0x19,
127 // clang-format on
128 };
Kim Paulhamus6efcf4952017-09-14 22:46:27129 std::vector<CBORValue> array;
Jun Choi06ae32d2017-12-21 18:52:39130 for (int64_t i = 1; i <= 25; i++) {
Kim Paulhamus6efcf4952017-09-14 22:46:27131 array.push_back(CBORValue(i));
132 }
Jun Choi0ca86672017-11-14 04:58:24133 auto cbor = CBORWriter::Write(CBORValue(array));
134 ASSERT_TRUE(cbor.has_value());
135 EXPECT_THAT(cbor.value(),
136 testing::ElementsAreArray(kArrayTestCaseCbor,
137 arraysize(kArrayTestCaseCbor)));
Kim Paulhamus6efcf4952017-09-14 22:46:27138}
139
Kouhei Ueno6d1629e2018-02-01 17:28:03140TEST(CBORWriterTest, TestWriteMap) {
Kim Paulhamus6efcf4952017-09-14 22:46:27141 static const uint8_t kMapTestCaseCbor[] = {
Adam Langley68672fd2017-10-17 19:35:27142 // clang-format off
Kouhei Ueno6d1629e2018-02-01 17:28:03143 0xb8, 0x19, // map of 25 pairs:
Jun Choi98a59e462017-12-14 23:04:09144 0x00, // key 0
145 0x61, 0x61, // value "a"
Adam Langley68672fd2017-10-17 19:35:27146
Jun Choi98a59e462017-12-14 23:04:09147 0x17, // key 23
148 0x61, 0x62, // value "b"
Adam Langley68672fd2017-10-17 19:35:27149
Jun Choi98a59e462017-12-14 23:04:09150 0x18, 0x18, // key 24
Jun Choi06ae32d2017-12-21 18:52:39151 0x61, 0x63, // value "c"
Adam Langley68672fd2017-10-17 19:35:27152
Jun Choi98a59e462017-12-14 23:04:09153 0x18, 0xFF, // key 255
154 0x61, 0x64, // value "d"
Adam Langley68672fd2017-10-17 19:35:27155
Jun Choi98a59e462017-12-14 23:04:09156 0x19, 0x01, 0x00, // key 256
157 0x61, 0x65, // value "e"
Adam Langley68672fd2017-10-17 19:35:27158
Jun Choi98a59e462017-12-14 23:04:09159 0x19, 0xFF, 0xFF, // key 65535
160 0x61, 0x66, // value "f"
161
162 0x1A, 0x00, 0x01, 0x00, 0x00, // key 65536
163 0x61, 0x67, // value "g"
164
165 0x1A, 0xFF, 0xFF, 0xFF, 0xFF, // key 4294967295
166 0x61, 0x68, // value "h"
167
168 // key 4294967296
169 0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
170 0x61, 0x69, // value "i"
171
Jun Choi06ae32d2017-12-21 18:52:39172 // key INT64_MAX
173 0x1b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
174 0x61, 0x6a, // value "j"
175
176 0x20, // key -1
177 0x61, 0x6b, // value "k"
178
179 0x37, // key -24
180 0x61, 0x6c, // value "l"
181
182 0x38, 0x18, // key -25
183 0x61, 0x6d, // value "m"
184
185 0x38, 0xFF, // key -256
186 0x61, 0x6e, // value "n"
187
188 0x39, 0x01, 0x00, // key -257
189 0x61, 0x6f, // value "o"
190
191 0x3A, 0x00, 0x01, 0x00, 0x00, // key -65537
192 0x61, 0x70, // value "p"
193
194 0x3A, 0xFF, 0xFF, 0xFF, 0xFF, // key -4294967296
195 0x61, 0x71, // value "q"
196
197 // key -4294967297
198 0x3B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
199 0x61, 0x72, // value "r"
200
201 // key INT64_MIN
202 0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
203 0x61, 0x73, // value "s"
204
Kouhei Ueno6d1629e2018-02-01 17:28:03205 0x41, 'a', // byte string "a"
206 0x02,
207
208 0x43, 'b', 'a', 'r', // byte string "bar"
209 0x03,
210
211 0x43, 'f', 'o', 'o', // byte string "foo"
212 0x04,
213
Jun Choi98a59e462017-12-14 23:04:09214 0x60, // key ""
215 0x61, 0x2e, // value "."
216
Jun Choi98a59e462017-12-14 23:04:09217 0x61, 0x65, // key "e"
218 0x61, 0x45, // value "E"
219
220 0x62, 0x61, 0x61, // key "aa"
221 0x62, 0x41, 0x41, // value "AA"
Adam Langley68672fd2017-10-17 19:35:27222 // clang-format on
223 };
Kim Paulhamus6efcf4952017-09-14 22:46:27224 CBORValue::MapValue map;
Adam Langley68672fd2017-10-17 19:35:27225 // Shorter strings sort first in CTAP, thus the “aa” value should be
226 // serialised last in the map.
Jun Choi98a59e462017-12-14 23:04:09227 map[CBORValue("aa")] = CBORValue("AA");
Jun Choi98a59e462017-12-14 23:04:09228 map[CBORValue("e")] = CBORValue("E");
Jun Choi98a59e462017-12-14 23:04:09229 // The empty string is shorter than all others, so should appear first among
230 // the strings.
231 map[CBORValue("")] = CBORValue(".");
232 // Map keys are sorted by major type, by byte length, and then by
233 // byte-wise lexical order. So all integer type keys should appear before
Jun Choi06ae32d2017-12-21 18:52:39234 // key "" and all positive integer keys should appear before negative integer
235 // keys.
236 map[CBORValue(-1)] = CBORValue("k");
237 map[CBORValue(-24)] = CBORValue("l");
238 map[CBORValue(-25)] = CBORValue("m");
239 map[CBORValue(-256)] = CBORValue("n");
240 map[CBORValue(-257)] = CBORValue("o");
241 map[CBORValue(-65537)] = CBORValue("p");
242 map[CBORValue(int64_t(-4294967296))] = CBORValue("q");
243 map[CBORValue(int64_t(-4294967297))] = CBORValue("r");
244 map[CBORValue(std::numeric_limits<int64_t>::min())] = CBORValue("s");
Kouhei Ueno6d1629e2018-02-01 17:28:03245 map[CBORValue(CBORValue::BinaryValue{'a'})] = CBORValue(2);
246 map[CBORValue(CBORValue::BinaryValue{'b', 'a', 'r'})] = CBORValue(3);
247 map[CBORValue(CBORValue::BinaryValue{'f', 'o', 'o'})] = CBORValue(4);
Jun Choi06ae32d2017-12-21 18:52:39248 map[CBORValue(0)] = CBORValue("a");
Jun Choi98a59e462017-12-14 23:04:09249 map[CBORValue(23)] = CBORValue("b");
250 map[CBORValue(24)] = CBORValue("c");
Jun Choi06ae32d2017-12-21 18:52:39251 map[CBORValue(std::numeric_limits<uint8_t>::max())] = CBORValue("d");
Jun Choi98a59e462017-12-14 23:04:09252 map[CBORValue(256)] = CBORValue("e");
Jun Choi06ae32d2017-12-21 18:52:39253 map[CBORValue(std::numeric_limits<uint16_t>::max())] = CBORValue("f");
Jun Choi98a59e462017-12-14 23:04:09254 map[CBORValue(65536)] = CBORValue("g");
Jun Choi06ae32d2017-12-21 18:52:39255 map[CBORValue(int64_t(std::numeric_limits<uint32_t>::max()))] =
256 CBORValue("h");
257 map[CBORValue(int64_t(4294967296))] = CBORValue("i");
258 map[CBORValue(std::numeric_limits<int64_t>::max())] = CBORValue("j");
Jun Choi0ca86672017-11-14 04:58:24259 auto cbor = CBORWriter::Write(CBORValue(map));
260 ASSERT_TRUE(cbor.has_value());
261 EXPECT_THAT(cbor.value(), testing::ElementsAreArray(
262 kMapTestCaseCbor, arraysize(kMapTestCaseCbor)));
Kim Paulhamus6efcf4952017-09-14 22:46:27263}
264
265TEST(CBORWriterTest, TestWriteMapWithArray) {
Adam Langley68672fd2017-10-17 19:35:27266 static const uint8_t kMapArrayTestCaseCbor[] = {
267 // clang-format off
268 0xa2, // map of 2 pairs
269 0x61, 0x61, // "a"
270 0x01,
271
272 0x61, 0x62, // "b"
273 0x82, // array with 2 elements
274 0x02,
275 0x03,
276 // clang-format on
277 };
Kim Paulhamus6efcf4952017-09-14 22:46:27278 CBORValue::MapValue map;
Jun Choi98a59e462017-12-14 23:04:09279 map[CBORValue("a")] = CBORValue(1);
Kim Paulhamus6efcf4952017-09-14 22:46:27280 CBORValue::ArrayValue array;
281 array.push_back(CBORValue(2));
282 array.push_back(CBORValue(3));
Jun Choi98a59e462017-12-14 23:04:09283 map[CBORValue("b")] = CBORValue(array);
Jun Choi0ca86672017-11-14 04:58:24284 auto cbor = CBORWriter::Write(CBORValue(map));
285 ASSERT_TRUE(cbor.has_value());
286 EXPECT_THAT(cbor.value(),
Kim Paulhamus6efcf4952017-09-14 22:46:27287 testing::ElementsAreArray(kMapArrayTestCaseCbor,
288 arraysize(kMapArrayTestCaseCbor)));
289}
290
291TEST(CBORWriterTest, TestWriteNestedMap) {
Adam Langley68672fd2017-10-17 19:35:27292 static const uint8_t kNestedMapTestCase[] = {
293 // clang-format off
294 0xa2, // map of 2 pairs
295 0x61, 0x61, // "a"
296 0x01,
297
298 0x61, 0x62, // "b"
299 0xa2, // map of 2 pairs
300 0x61, 0x63, // "c"
301 0x02,
302
303 0x61, 0x64, // "d"
304 0x03,
305 // clang-format on
306 };
Kim Paulhamus6efcf4952017-09-14 22:46:27307 CBORValue::MapValue map;
Jun Choi98a59e462017-12-14 23:04:09308 map[CBORValue("a")] = CBORValue(1);
Kim Paulhamus6efcf4952017-09-14 22:46:27309 CBORValue::MapValue nested_map;
Jun Choi98a59e462017-12-14 23:04:09310 nested_map[CBORValue("c")] = CBORValue(2);
311 nested_map[CBORValue("d")] = CBORValue(3);
312 map[CBORValue("b")] = CBORValue(nested_map);
Jun Choi0ca86672017-11-14 04:58:24313 auto cbor = CBORWriter::Write(CBORValue(map));
314 ASSERT_TRUE(cbor.has_value());
315 EXPECT_THAT(cbor.value(),
316 testing::ElementsAreArray(kNestedMapTestCase,
317 arraysize(kNestedMapTestCase)));
318}
319
Kouhei Ueno6d1629e2018-02-01 17:28:03320TEST(CBORWriterTest, TestSignedExchangeExample) {
321 // Example adopted from:
322 // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html
323 static const uint8_t kSignedExchangeExample[] = {
324 // clang-format off
325 0xa5, // map of 5 pairs
326 0x0a, // 10
327 0x01,
328
329 0x18, 0x64, // 100
330 0x02,
331
332 0x20, // -1
333 0x03,
334
335 0x61, 'z', // text string "z"
336 0x04,
337
338 0x62, 'a', 'a', // text string "aa"
339 0x05,
340
341 /*
342 0x81, 0x18, 0x64, // [100] (array as map key is not yet supported)
343 0x06,
344
345 0x81, 0x20, // [-1] (array as map key is not yet supported)
346 0x07,
347
348 0xf4, // false (boolean as map key is not yet supported)
349 0x08,
350 */
351 // clang-format on
352 };
353 CBORValue::MapValue map;
354 map[CBORValue(10)] = CBORValue(1);
355 map[CBORValue(100)] = CBORValue(2);
356 map[CBORValue(-1)] = CBORValue(3);
357 map[CBORValue("z")] = CBORValue(4);
358 map[CBORValue("aa")] = CBORValue(5);
359
360 auto cbor = CBORWriter::Write(CBORValue(map));
361 ASSERT_TRUE(cbor.has_value());
362 EXPECT_THAT(cbor.value(),
363 testing::ElementsAreArray(kSignedExchangeExample,
364 arraysize(kSignedExchangeExample)));
365}
366
Jun Choi07540c62017-12-21 02:51:43367TEST(CBORWriterTest, TestWriteSimpleValue) {
368 static const struct {
369 CBORValue::SimpleValue simple_value;
370 const base::StringPiece cbor;
371 } kSimpleTestCase[] = {
372 {CBORValue::SimpleValue::FALSE_VALUE, base::StringPiece("\xf4")},
373 {CBORValue::SimpleValue::TRUE_VALUE, base::StringPiece("\xf5")},
374 {CBORValue::SimpleValue::NULL_VALUE, base::StringPiece("\xf6")},
375 {CBORValue::SimpleValue::UNDEFINED, base::StringPiece("\xf7")}};
376
377 for (const auto& test_case : kSimpleTestCase) {
378 auto cbor = CBORWriter::Write(CBORValue(test_case.simple_value));
379 ASSERT_TRUE(cbor.has_value());
380 EXPECT_THAT(cbor.value(), testing::ElementsAreArray(test_case.cbor));
381 }
382}
383
Jun Choi0ca86672017-11-14 04:58:24384// For major type 0, 2, 3, empty CBOR array, and empty CBOR map, the nesting
385// depth is expected to be 0 since the CBOR decoder does not need to parse
386// any nested CBOR value elements.
387TEST(CBORWriterTest, TestWriteSingleLayer) {
388 const CBORValue simple_uint = CBORValue(1);
389 const CBORValue simple_string = CBORValue("a");
390 const std::vector<uint8_t> byte_data = {0x01, 0x02, 0x03, 0x04};
391 const CBORValue simple_bytestring = CBORValue(byte_data);
392 CBORValue::ArrayValue empty_cbor_array;
393 CBORValue::MapValue empty_cbor_map;
394 const CBORValue empty_array_value = CBORValue(empty_cbor_array);
395 const CBORValue empty_map_value = CBORValue(empty_cbor_map);
396 CBORValue::ArrayValue simple_array;
397 simple_array.push_back(CBORValue(2));
398 CBORValue::MapValue simple_map;
Jun Choi98a59e462017-12-14 23:04:09399 simple_map[CBORValue("b")] = CBORValue(3);
Jun Choi0ca86672017-11-14 04:58:24400 const CBORValue single_layer_cbor_map = CBORValue(simple_map);
401 const CBORValue single_layer_cbor_array = CBORValue(simple_array);
402
403 EXPECT_TRUE(CBORWriter::Write(simple_uint, 0).has_value());
404 EXPECT_TRUE(CBORWriter::Write(simple_string, 0).has_value());
405 EXPECT_TRUE(CBORWriter::Write(simple_bytestring, 0).has_value());
406
407 EXPECT_TRUE(CBORWriter::Write(empty_array_value, 0).has_value());
408 EXPECT_TRUE(CBORWriter::Write(empty_map_value, 0).has_value());
409
410 EXPECT_FALSE(CBORWriter::Write(single_layer_cbor_array, 0).has_value());
411 EXPECT_TRUE(CBORWriter::Write(single_layer_cbor_array, 1).has_value());
412
413 EXPECT_FALSE(CBORWriter::Write(single_layer_cbor_map, 0).has_value());
414 EXPECT_TRUE(CBORWriter::Write(single_layer_cbor_map, 1).has_value());
415}
416
417// Major type 5 nested CBOR map value with following structure.
418// {"a": 1,
419// "b": {"c": 2,
420// "d": 3}}
421TEST(CBORWriterTest, NestedMaps) {
422 CBORValue::MapValue cbor_map;
Jun Choi98a59e462017-12-14 23:04:09423 cbor_map[CBORValue("a")] = CBORValue(1);
Jun Choi0ca86672017-11-14 04:58:24424 CBORValue::MapValue nested_map;
Jun Choi98a59e462017-12-14 23:04:09425 nested_map[CBORValue("c")] = CBORValue(2);
426 nested_map[CBORValue("d")] = CBORValue(3);
427 cbor_map[CBORValue("b")] = CBORValue(nested_map);
Jun Choi0ca86672017-11-14 04:58:24428 EXPECT_TRUE(CBORWriter::Write(CBORValue(cbor_map), 2).has_value());
429 EXPECT_FALSE(CBORWriter::Write(CBORValue(cbor_map), 1).has_value());
430}
431
432// Testing Write() function for following CBOR structure with depth of 3.
433// [1,
434// 2,
435// 3,
436// {"a": 1,
437// "b": {"c": 2,
438// "d": 3}}]
439TEST(CBORWriterTest, UnbalancedNestedContainers) {
440 CBORValue::ArrayValue cbor_array;
441 CBORValue::MapValue cbor_map;
442 CBORValue::MapValue nested_map;
443
Jun Choi98a59e462017-12-14 23:04:09444 cbor_map[CBORValue("a")] = CBORValue(1);
445 nested_map[CBORValue("c")] = CBORValue(2);
446 nested_map[CBORValue("d")] = CBORValue(3);
447 cbor_map[CBORValue("b")] = CBORValue(nested_map);
Jun Choi0ca86672017-11-14 04:58:24448 cbor_array.push_back(CBORValue(1));
449 cbor_array.push_back(CBORValue(2));
450 cbor_array.push_back(CBORValue(3));
451 cbor_array.push_back(CBORValue(cbor_map));
452
453 EXPECT_TRUE(CBORWriter::Write(CBORValue(cbor_array), 3).has_value());
454 EXPECT_FALSE(CBORWriter::Write(CBORValue(cbor_array), 2).has_value());
455}
456
457// Testing Write() function for following CBOR structure.
458// {"a": 1,
459// "b": {"c": 2,
460// "d": 3
461// "h": { "e": 4,
462// "f": 5,
463// "g": [6, 7, [8]]}}}
464// Since above CBOR contains 5 nesting levels. Thus, Write() is expected to
465// return empty optional object when maximum nesting layer size is set to 4.
466TEST(CBORWriterTest, OverlyNestedCBOR) {
467 CBORValue::MapValue map;
468 CBORValue::MapValue nested_map;
469 CBORValue::MapValue inner_nested_map;
470 CBORValue::ArrayValue inner_array;
471 CBORValue::ArrayValue array;
472
Jun Choi98a59e462017-12-14 23:04:09473 map[CBORValue("a")] = CBORValue(1);
474 nested_map[CBORValue("c")] = CBORValue(2);
475 nested_map[CBORValue("d")] = CBORValue(3);
476 inner_nested_map[CBORValue("e")] = CBORValue(4);
477 inner_nested_map[CBORValue("f")] = CBORValue(5);
Jun Choi0ca86672017-11-14 04:58:24478 inner_array.push_back(CBORValue(6));
479 array.push_back(CBORValue(6));
480 array.push_back(CBORValue(7));
481 array.push_back(CBORValue(inner_array));
Jun Choi98a59e462017-12-14 23:04:09482 inner_nested_map[CBORValue("g")] = CBORValue(array);
483 nested_map[CBORValue("h")] = CBORValue(inner_nested_map);
484 map[CBORValue("b")] = CBORValue(nested_map);
Jun Choi0ca86672017-11-14 04:58:24485
486 EXPECT_TRUE(CBORWriter::Write(CBORValue(map), 5).has_value());
487 EXPECT_FALSE(CBORWriter::Write(CBORValue(map), 4).has_value());
Kim Paulhamus6efcf4952017-09-14 22:46:27488}
489
Jun Choi9f1446c02017-12-21 23:33:27490} // namespace cbor