node_test.cpp 19.7 KB
Newer Older
1
#include "yaml-cpp/node/node.h"
2
#include "yaml-cpp/emitter.h"
3
4
#include "yaml-cpp/node/convert.h"
#include "yaml-cpp/node/detail/impl.h"
5
#include "yaml-cpp/node/emit.h"
Jesse Beder's avatar
Jesse Beder committed
6
7
8
#include "yaml-cpp/node/impl.h"
#include "yaml-cpp/node/iterator.h"

9
#include "gmock/gmock.h"
Jesse Beder's avatar
Jesse Beder committed
10
#include "gtest/gtest.h"
Jesse Beder's avatar
Jesse Beder committed
11

12
13
#include <sstream>

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
namespace {

// malloc/free based allocator just for testing custom allocators on stl containers
template <class T>
class CustomAllocator : public std::allocator<T> {
  public:
    typedef std::size_t     size_type;
    typedef std::ptrdiff_t  difference_type;
    typedef T*              pointer;
    typedef const T*        const_pointer;
    typedef T&              reference;
    typedef const T&        const_reference;
    typedef T               value_type;
    template<class U> struct rebind { typedef CustomAllocator<U> other; };
    CustomAllocator() : std::allocator<T>() {}
    CustomAllocator(const CustomAllocator& other) : std::allocator<T>(other) {}
    template<class U> CustomAllocator(const CustomAllocator<U>& other) : std::allocator<T>(other) {}
    ~CustomAllocator() {}
    size_type max_size() const { return (std::numeric_limits<std::ptrdiff_t>::max)()/sizeof(T); }
    pointer allocate(size_type num, const void* /*hint*/ = 0) {
      if (num > std::size_t(-1) / sizeof(T)) throw std::bad_alloc();
      return static_cast<pointer>(malloc(num * sizeof(T)));
    }
    void deallocate(pointer p, size_type /*num*/) { free(p); }
};

template <class T> using CustomVector = std::vector<T,CustomAllocator<T>>;
template <class T> using CustomList = std::list<T,CustomAllocator<T>>;
template <class K, class V, class C=std::less<K>> using CustomMap = std::map<K,V,C,CustomAllocator<std::pair<const K,V>>>;
43
template <class K, class V, class H=std::hash<K>, class P=std::equal_to<K>> using CustomUnorderedMap = std::unordered_map<K,V,H,P,CustomAllocator<std::pair<const K,V>>>;
44
45
46

}  // anonymous namespace

47
48
49
using ::testing::AnyOf;
using ::testing::Eq;

50
51
#define EXPECT_THROW_REPRESENTATION_EXCEPTION(statement, message) \
  ASSERT_THROW(statement, RepresentationException);               \
Jesse Beder's avatar
Jesse Beder committed
52
53
  try {                                                           \
    statement;                                                    \
54
  } catch (const RepresentationException& e) {                    \
Jesse Beder's avatar
Jesse Beder committed
55
    EXPECT_EQ(e.msg, message);                                    \
56
57
  }

Jesse Beder's avatar
Jesse Beder committed
58
59
namespace YAML {
namespace {
Jesse Beder's avatar
Jesse Beder committed
60
TEST(NodeTest, SimpleScalar) {
61
  Node node = Node("Hello, World!");
Jesse Beder's avatar
Jesse Beder committed
62
63
64
65
66
  EXPECT_TRUE(node.IsScalar());
  EXPECT_EQ("Hello, World!", node.as<std::string>());
}

TEST(NodeTest, IntScalar) {
67
  Node node = Node(15);
Jesse Beder's avatar
Jesse Beder committed
68
69
70
71
72
  EXPECT_TRUE(node.IsScalar());
  EXPECT_EQ(15, node.as<int>());
}

TEST(NodeTest, SimpleAppendSequence) {
73
  Node node;
Jesse Beder's avatar
Jesse Beder committed
74
75
76
77
78
79
80
81
82
83
84
  node.push_back(10);
  node.push_back("foo");
  node.push_back("monkey");
  EXPECT_TRUE(node.IsSequence());
  EXPECT_EQ(3, node.size());
  EXPECT_EQ(10, node[0].as<int>());
  EXPECT_EQ("foo", node[1].as<std::string>());
  EXPECT_EQ("monkey", node[2].as<std::string>());
  EXPECT_TRUE(node.IsSequence());
}

85
86
87
88
89
90
91
92
93
94
95
96
TEST(NodeTest, SequenceElementRemoval) {
  Node node;
  node[0] = "a";
  node[1] = "b";
  node[2] = "c";
  node.remove(1);
  EXPECT_TRUE(node.IsSequence());
  EXPECT_EQ(2, node.size());
  EXPECT_EQ("a", node[0].as<std::string>());
  EXPECT_EQ("c", node[1].as<std::string>());
}

97
98
99
100
101
102
103
104
105
106
107
108
109
TEST(NodeTest, SequenceElementRemovalSizeCheck) {
  Node node;
  node[0] = "a";
  node[1] = "b";
  node[2] = "c";
  EXPECT_EQ(3, node.size());
  node.remove(1);
  EXPECT_TRUE(node.IsSequence());
  EXPECT_EQ(2, node.size());
  EXPECT_EQ("a", node[0].as<std::string>());
  EXPECT_EQ("c", node[1].as<std::string>());
}

110
111
112
113
114
115
116
117
118
119
120
121
TEST(NodeTest, SequenceFirstElementRemoval) {
  Node node;
  node[0] = "a";
  node[1] = "b";
  node[2] = "c";
  node.remove(0);
  EXPECT_TRUE(node.IsSequence());
  EXPECT_EQ(2, node.size());
  EXPECT_EQ("b", node[0].as<std::string>());
  EXPECT_EQ("c", node[1].as<std::string>());
}

122
123
124
125
126
127
128
129
130
131
132
133
134
TEST(NodeTest, SequenceFirstElementRemovalSizeCheck) {
  Node node;
  node[0] = "a";
  node[1] = "b";
  node[2] = "c";
  EXPECT_EQ(3, node.size());
  node.remove(0);
  EXPECT_TRUE(node.IsSequence());
  EXPECT_EQ(2, node.size());
  EXPECT_EQ("b", node[0].as<std::string>());
  EXPECT_EQ("c", node[1].as<std::string>());
}

135
136
137
138
139
140
141
142
143
144
145
146
TEST(NodeTest, SequenceLastElementRemoval) {
  Node node;
  node[0] = "a";
  node[1] = "b";
  node[2] = "c";
  node.remove(2);
  EXPECT_TRUE(node.IsSequence());
  EXPECT_EQ(2, node.size());
  EXPECT_EQ("a", node[0].as<std::string>());
  EXPECT_EQ("b", node[1].as<std::string>());
}

147
148
149
150
151
152
153
154
155
156
157
158
159
TEST(NodeTest, SequenceLastElementRemovalSizeCheck) {
  Node node;
  node[0] = "a";
  node[1] = "b";
  node[2] = "c";
  EXPECT_EQ(3, node.size());
  node.remove(2);
  EXPECT_TRUE(node.IsSequence());
  EXPECT_EQ(2, node.size());
  EXPECT_EQ("a", node[0].as<std::string>());
  EXPECT_EQ("b", node[1].as<std::string>());
}

160
161
162
163
164
165
166
167
168
169
170
171
172
TEST(NodeTest, NodeAssignment) {
  Node node1;
  Node node2;
  node1[1] = 1;
  node1[2] = 2;
  node1[3] = 3;
  node2 = node1;
  EXPECT_EQ(node1, node2);
  EXPECT_EQ(node1[1], node2[1]);
  EXPECT_EQ(node1[2], node2[2]);
  EXPECT_EQ(node1[3], node2[3]);
}

173
174
175
176
177
178
179
180
181
182
183
184
185
186
TEST(NodeTest, EqualRepresentationAfterMoveAssignment) {
  Node node1;
  Node node2;
  std::ostringstream ss1, ss2;
  node1["foo"] = "bar";
  ss1 << node1;
  node2["hello"] = "world";
  node2 = std::move(node1);
  ss2 << node2;
  EXPECT_FALSE(node2["hello"]);
  EXPECT_EQ("bar", node2["foo"].as<std::string>());
  EXPECT_EQ(ss1.str(), ss2.str());
}

187
188
189
190
191
192
193
TEST(NodeTest, MapElementRemoval) {
  Node node;
  node["foo"] = "bar";
  node.remove("foo");
  EXPECT_TRUE(!node["foo"]);
}

194
195
196
197
198
199
200
201
202
203
TEST(NodeTest, MapIntegerElementRemoval) {
  Node node;
  node[1] = "hello";
  node[2] = 'c';
  node["foo"] = "bar";
  EXPECT_TRUE(node.IsMap());
  node.remove(1);
  EXPECT_TRUE(node.IsMap());
}

Jesse Beder's avatar
Jesse Beder committed
204
TEST(NodeTest, SimpleAssignSequence) {
205
  Node node;
Jesse Beder's avatar
Jesse Beder committed
206
207
208
209
210
211
212
213
214
215
216
217
  node[0] = 10;
  node[1] = "foo";
  node[2] = "monkey";
  EXPECT_TRUE(node.IsSequence());
  EXPECT_EQ(3, node.size());
  EXPECT_EQ(10, node[0].as<int>());
  EXPECT_EQ("foo", node[1].as<std::string>());
  EXPECT_EQ("monkey", node[2].as<std::string>());
  EXPECT_TRUE(node.IsSequence());
}

TEST(NodeTest, SimpleMap) {
218
  Node node;
Jesse Beder's avatar
Jesse Beder committed
219
220
221
222
223
224
225
  node["key"] = "value";
  EXPECT_TRUE(node.IsMap());
  EXPECT_EQ("value", node["key"].as<std::string>());
  EXPECT_EQ(1, node.size());
}

TEST(NodeTest, MapWithUndefinedValues) {
226
  Node node;
Jesse Beder's avatar
Jesse Beder committed
227
228
229
230
231
232
233
234
235
236
237
  node["key"] = "value";
  node["undefined"];
  EXPECT_TRUE(node.IsMap());
  EXPECT_EQ("value", node["key"].as<std::string>());
  EXPECT_EQ(1, node.size());

  node["undefined"] = "monkey";
  EXPECT_EQ("monkey", node["undefined"].as<std::string>());
  EXPECT_EQ(2, node.size());
}

238
239
240
241
242
243
244
245
246
247
248
TEST(NodeTest, SeqIntoMap) {
  Node node;
  node[0] = "test";
  node[1];
  node[2] = "value";
  EXPECT_TRUE(node.IsMap());
  EXPECT_EQ("test", node[0].as<std::string>());
  EXPECT_EQ("value", node[2].as<std::string>());
  EXPECT_EQ(2, node.size());
}

249
250
251
252
TEST(NodeTest, RemoveUnassignedNode) {
  Node node(NodeType::Map);
  node["key"];
  node.remove("key");
253
  EXPECT_EQ(0, node.size());
254
255
}

256
257
258
259
260
261
262
263
TEST(NodeTest, RemoveUnassignedNodeFromMap) {
  Node node(NodeType::Map);
  Node n;
  node[n];
  node.remove(n);
  EXPECT_EQ(0, node.size());
}

264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
TEST(NodeTest, MapForceInsert) {
  Node node;
  Node k1("k1");
  Node k2("k2");
  Node v1("v1");
  Node v2("v2");
  node[k1] = v1;
  node[k2] = v1;
  EXPECT_TRUE(node.IsMap());
  EXPECT_EQ("v1", node["k1"].as<std::string>());
  EXPECT_EQ("v1", node["k2"].as<std::string>());
  EXPECT_EQ(2, node.size());

  node.force_insert(k2, v2);
  EXPECT_EQ("v1", node["k1"].as<std::string>());
279
280
  EXPECT_EQ("v1", node["k2"].as<std::string>());
  EXPECT_EQ(3, node.size());
281
282
}

283
284
285
286
287
288
TEST(NodeTest, UndefinedConstNodeWithFallback) {
  Node node;
  const Node& cn = node;
  EXPECT_EQ(cn["undefined"].as<int>(3), 3);
}

Jesse Beder's avatar
Jesse Beder committed
289
TEST(NodeTest, MapIteratorWithUndefinedValues) {
290
  Node node;
Jesse Beder's avatar
Jesse Beder committed
291
292
293
294
295
296
297
298
299
  node["key"] = "value";
  node["undefined"];

  std::size_t count = 0;
  for (const_iterator it = node.begin(); it != node.end(); ++it)
    count++;
  EXPECT_EQ(1, count);
}

300
301
302
303
304
305
306
307
TEST(NodeTest, ConstIteratorOnConstUndefinedNode) {
  Node node;
  const Node& cn = node;
  const Node& undefinedCn = cn["undefined"];

  std::size_t count = 0;
  for (const_iterator it = undefinedCn.begin(); it != undefinedCn.end(); ++it) {
    count++;
Jesse Beder's avatar
Jesse Beder committed
308
  }
309
310
311
312
313
314
315
316
317
318
319
  EXPECT_EQ(0, count);
}

TEST(NodeTest, IteratorOnConstUndefinedNode) {
  Node node;
  const Node& cn = node;
  const Node& undefinedCn = cn["undefined"];

  Node& nonConstUndefinedNode = const_cast<Node&>(undefinedCn);

  std::size_t count = 0;
Jesse Beder's avatar
Jesse Beder committed
320
321
  for (iterator it = nonConstUndefinedNode.begin();
       it != nonConstUndefinedNode.end(); ++it) {
322
323
324
325
326
    count++;
  }
  EXPECT_EQ(0, count);
}

Jesse Beder's avatar
Jesse Beder committed
327
TEST(NodeTest, SimpleSubkeys) {
328
  Node node;
Jesse Beder's avatar
Jesse Beder committed
329
330
331
332
333
334
335
336
337
338
  node["device"]["udid"] = "12345";
  node["device"]["name"] = "iPhone";
  node["device"]["os"] = "4.0";
  node["username"] = "monkey";
  EXPECT_EQ("12345", node["device"]["udid"].as<std::string>());
  EXPECT_EQ("iPhone", node["device"]["name"].as<std::string>());
  EXPECT_EQ("4.0", node["device"]["os"].as<std::string>());
  EXPECT_EQ("monkey", node["username"].as<std::string>());
}

339
TEST(NodeTest, StdArray) {
Jesse Beder's avatar
Jesse Beder committed
340
  std::array<int, 5> evens{{2, 4, 6, 8, 10}};
341
342
343
344
345
346
347
  Node node;
  node["evens"] = evens;
  std::array<int, 5> actualEvens = node["evens"].as<std::array<int, 5>>();
  EXPECT_EQ(evens, actualEvens);
}

TEST(NodeTest, StdArrayWrongSize) {
Jesse Beder's avatar
Jesse Beder committed
348
  std::array<int, 3> evens{{2, 4, 6}};
349
350
  Node node;
  node["evens"] = evens;
Jesse Beder's avatar
Jesse Beder committed
351
352
  EXPECT_THROW_REPRESENTATION_EXCEPTION(
      (node["evens"].as<std::array<int, 5>>()), ErrorMsg::BAD_CONVERSION);
353
354
}

Jesse Beder's avatar
Jesse Beder committed
355
356
357
358
359
360
361
362
363
TEST(NodeTest, StdVector) {
  std::vector<int> primes;
  primes.push_back(2);
  primes.push_back(3);
  primes.push_back(5);
  primes.push_back(7);
  primes.push_back(11);
  primes.push_back(13);

364
  Node node;
Jesse Beder's avatar
Jesse Beder committed
365
  node["primes"] = primes;
Jesse Beder's avatar
Jesse Beder committed
366
  EXPECT_EQ(primes, node["primes"].as<std::vector<int>>());
Jesse Beder's avatar
Jesse Beder committed
367
368
}

369
370
371
372
373
374
375
376
377
378
379
380
381
382
TEST(NodeTest, StdVectorWithCustomAllocator) {
  CustomVector<int> primes;
  primes.push_back(2);
  primes.push_back(3);
  primes.push_back(5);
  primes.push_back(7);
  primes.push_back(11);
  primes.push_back(13);

  Node node;
  node["primes"] = primes;
  EXPECT_EQ(primes, node["primes"].as<CustomVector<int>>());
}

Jesse Beder's avatar
Jesse Beder committed
383
384
385
386
387
388
389
390
391
TEST(NodeTest, StdList) {
  std::list<int> primes;
  primes.push_back(2);
  primes.push_back(3);
  primes.push_back(5);
  primes.push_back(7);
  primes.push_back(11);
  primes.push_back(13);

392
  Node node;
Jesse Beder's avatar
Jesse Beder committed
393
  node["primes"] = primes;
Jesse Beder's avatar
Jesse Beder committed
394
  EXPECT_EQ(primes, node["primes"].as<std::list<int>>());
Jesse Beder's avatar
Jesse Beder committed
395
396
}

397
398
399
400
401
402
403
404
405
406
407
408
409
410
TEST(NodeTest, StdListWithCustomAllocator) {
  CustomList<int> primes;
  primes.push_back(2);
  primes.push_back(3);
  primes.push_back(5);
  primes.push_back(7);
  primes.push_back(11);
  primes.push_back(13);

  Node node;
  node["primes"] = primes;
  EXPECT_EQ(primes, node["primes"].as<CustomList<int>>());
}

Jesse Beder's avatar
Jesse Beder committed
411
412
413
414
415
416
417
418
TEST(NodeTest, StdMap) {
  std::map<int, int> squares;
  squares[0] = 0;
  squares[1] = 1;
  squares[2] = 4;
  squares[3] = 9;
  squares[4] = 16;

419
  Node node;
Jesse Beder's avatar
Jesse Beder committed
420
  node["squares"] = squares;
Jesse Beder's avatar
Jesse Beder committed
421
  std::map<int, int> actualSquares = node["squares"].as<std::map<int, int>>();
Jesse Beder's avatar
Jesse Beder committed
422
423
424
  EXPECT_EQ(squares, actualSquares);
}

425
426
427
428
429
430
431
432
433
434
435
436
437
438
TEST(NodeTest, StdMapWithCustomAllocator) {
  CustomMap<int,int> squares;
  squares[0] = 0;
  squares[1] = 1;
  squares[2] = 4;
  squares[3] = 9;
  squares[4] = 16;

  Node node;
  node["squares"] = squares;
  CustomMap<int,int> actualSquares = node["squares"].as<CustomMap<int,int>>();
  EXPECT_EQ(squares, actualSquares);
}

439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
TEST(NodeTest, StdUnorderedMap) {
  std::unordered_map<int, int> squares;
  squares[0] = 0;
  squares[1] = 1;
  squares[2] = 4;
  squares[3] = 9;
  squares[4] = 16;

  Node node;
  node["squares"] = squares;
  std::unordered_map<int, int> actualSquares = node["squares"].as<std::unordered_map<int, int>>();
  EXPECT_EQ(squares, actualSquares);
}

TEST(NodeTest, StdUnorderedMapWithCustomAllocator) {
  CustomUnorderedMap<int,int> squares;
  squares[0] = 0;
  squares[1] = 1;
  squares[2] = 4;
  squares[3] = 9;
  squares[4] = 16;

  Node node;
  node["squares"] = squares;
  CustomUnorderedMap<int,int> actualSquares = node["squares"].as<CustomUnorderedMap<int,int>>();
  EXPECT_EQ(squares, actualSquares);
}

Jesse Beder's avatar
Jesse Beder committed
467
468
469
470
471
TEST(NodeTest, StdPair) {
  std::pair<int, std::string> p;
  p.first = 5;
  p.second = "five";

472
  Node node;
Jesse Beder's avatar
Jesse Beder committed
473
474
  node["pair"] = p;
  std::pair<int, std::string> actualP =
Jesse Beder's avatar
Jesse Beder committed
475
      node["pair"].as<std::pair<int, std::string>>();
Jesse Beder's avatar
Jesse Beder committed
476
477
478
479
  EXPECT_EQ(p, actualP);
}

TEST(NodeTest, SimpleAlias) {
480
  Node node;
Jesse Beder's avatar
Jesse Beder committed
481
482
483
484
485
486
487
488
489
  node["foo"] = "value";
  node["bar"] = node["foo"];
  EXPECT_EQ("value", node["foo"].as<std::string>());
  EXPECT_EQ("value", node["bar"].as<std::string>());
  EXPECT_EQ(node["bar"], node["foo"]);
  EXPECT_EQ(2, node.size());
}

TEST(NodeTest, AliasAsKey) {
490
  Node node;
Jesse Beder's avatar
Jesse Beder committed
491
  node["foo"] = "value";
492
  Node value = node["foo"];
Jesse Beder's avatar
Jesse Beder committed
493
494
495
496
497
498
499
500
  node[value] = "foo";
  EXPECT_EQ("value", node["foo"].as<std::string>());
  EXPECT_EQ("foo", node[value].as<std::string>());
  EXPECT_EQ("foo", node["value"].as<std::string>());
  EXPECT_EQ(2, node.size());
}

TEST(NodeTest, SelfReferenceSequence) {
501
  Node node;
Jesse Beder's avatar
Jesse Beder committed
502
503
504
505
506
507
508
509
510
  node[0] = node;
  EXPECT_TRUE(node.IsSequence());
  EXPECT_EQ(1, node.size());
  EXPECT_EQ(node, node[0]);
  EXPECT_EQ(node, node[0][0]);
  EXPECT_EQ(node[0], node[0][0]);
}

TEST(NodeTest, ValueSelfReferenceMap) {
511
  Node node;
Jesse Beder's avatar
Jesse Beder committed
512
513
514
515
516
517
518
519
520
  node["key"] = node;
  EXPECT_TRUE(node.IsMap());
  EXPECT_EQ(1, node.size());
  EXPECT_EQ(node, node["key"]);
  EXPECT_EQ(node, node["key"]["key"]);
  EXPECT_EQ(node["key"], node["key"]["key"]);
}

TEST(NodeTest, KeySelfReferenceMap) {
521
  Node node;
Jesse Beder's avatar
Jesse Beder committed
522
523
524
525
526
527
528
  node[node] = "value";
  EXPECT_TRUE(node.IsMap());
  EXPECT_EQ(1, node.size());
  EXPECT_EQ("value", node[node].as<std::string>());
}

TEST(NodeTest, SelfReferenceMap) {
529
  Node node;
Jesse Beder's avatar
Jesse Beder committed
530
531
532
533
534
535
536
537
538
  node[node] = node;
  EXPECT_TRUE(node.IsMap());
  EXPECT_EQ(1, node.size());
  EXPECT_EQ(node, node[node]);
  EXPECT_EQ(node, node[node][node]);
  EXPECT_EQ(node[node], node[node][node]);
}

TEST(NodeTest, TempMapVariable) {
539
540
  Node node;
  Node tmp = node["key"];
Jesse Beder's avatar
Jesse Beder committed
541
542
543
544
545
546
547
  tmp = "value";
  EXPECT_TRUE(node.IsMap());
  EXPECT_EQ(1, node.size());
  EXPECT_EQ("value", node["key"].as<std::string>());
}

TEST(NodeTest, TempMapVariableAlias) {
548
549
  Node node;
  Node tmp = node["key"];
Jesse Beder's avatar
Jesse Beder committed
550
551
552
553
554
555
556
557
558
559
  tmp = node["other"];
  node["other"] = "value";
  EXPECT_TRUE(node.IsMap());
  EXPECT_EQ(2, node.size());
  EXPECT_EQ("value", node["key"].as<std::string>());
  EXPECT_EQ("value", node["other"].as<std::string>());
  EXPECT_EQ(node["key"], node["other"]);
}

TEST(NodeTest, Bool) {
560
  Node node;
Jesse Beder's avatar
Jesse Beder committed
561
562
563
564
565
566
  node[true] = false;
  EXPECT_TRUE(node.IsMap());
  EXPECT_EQ(false, node[true].as<bool>());
}

TEST(NodeTest, AutoBoolConversion) {
567
#ifdef _MSC_VER
Jesse Beder's avatar
Jesse Beder committed
568
#pragma warning(disable : 4800)
569
#endif
570
  Node node;
Jesse Beder's avatar
Jesse Beder committed
571
572
573
574
575
576
  node["foo"] = "bar";
  EXPECT_TRUE(static_cast<bool>(node["foo"]));
  EXPECT_TRUE(!node["monkey"]);
  EXPECT_TRUE(!!node["foo"]);
}

577
578
579
580
581
582
TEST(NodeTest, FloatingPrecisionFloat) {
  const float x = 0.123456789;
  Node node = Node(x);
  EXPECT_EQ(x, node.as<float>());
}

583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
TEST(NodeTest, FloatingPrecisionPositiveInfinityFloat) {
  if (!std::numeric_limits<float>::has_infinity) {
    return;
  }
  const float x = std::numeric_limits<float>::infinity();
  Node node = Node(x);
  EXPECT_EQ(x, node.as<float>());
}

TEST(NodeTest, FloatingPrecisionNegativeInfinityFloat) {
  if (!std::numeric_limits<float>::has_infinity) {
    return;
  }
  const float x = -std::numeric_limits<float>::infinity();
  Node node = Node(x);
  EXPECT_EQ(x, node.as<float>());
}

TEST(NodeTest, FloatingPrecisionNanFloat) {
  if (!std::numeric_limits<float>::has_quiet_NaN) {
    return;
  }
  const float x = std::numeric_limits<float>::quiet_NaN();
  Node node = Node(x);
  EXPECT_TRUE(std::isnan(node.as<float>()));
}

610
TEST(NodeTest, FloatingPrecisionDouble) {
Jesse Beder's avatar
Jesse Beder committed
611
  const double x = 0.123456789;
612
  Node node = Node(x);
Jesse Beder's avatar
Jesse Beder committed
613
614
615
  EXPECT_EQ(x, node.as<double>());
}

616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
TEST(NodeTest, FloatingPrecisionPositiveInfinityDouble) {
  if (!std::numeric_limits<double>::has_infinity) {
    return;
  }
  const double x = std::numeric_limits<double>::infinity();
  Node node = Node(x);
  EXPECT_EQ(x, node.as<float>());
}

TEST(NodeTest, FloatingPrecisionNegativeInfinityDouble) {
  if (!std::numeric_limits<double>::has_infinity) {
    return;
  }
  const double x = -std::numeric_limits<double>::infinity();
  Node node = Node(x);
  EXPECT_EQ(x, node.as<double>());
}

TEST(NodeTest, FloatingPrecisionNanDouble) {
  if (!std::numeric_limits<double>::has_quiet_NaN) {
    return;
  }
  const double x = std::numeric_limits<double>::quiet_NaN();
  Node node = Node(x);
  EXPECT_TRUE(std::isnan(node.as<double>()));
}

Jesse Beder's avatar
Jesse Beder committed
643
TEST(NodeTest, SpaceChar) {
644
  Node node = Node(' ');
Jesse Beder's avatar
Jesse Beder committed
645
646
647
  EXPECT_EQ(' ', node.as<char>());
}

Jesse Beder's avatar
Jesse Beder committed
648
649
650
651
652
TEST(NodeTest, CloneNull) {
  Node node;
  Node clone = Clone(node);
  EXPECT_EQ(NodeType::Null, clone.Type());
}
653

654
655
656
657
658
659
TEST(NodeTest, KeyNodeExitsScope) {
  Node node;
  {
    Node temp("Hello, world");
    node[temp] = 0;
  }
660
661
  for (Node::const_iterator it = node.begin(); it != node.end(); ++it) {
    (void)it;
662
663
  }
}
Jesse Beder's avatar
Merge  
Jesse Beder committed
664

665
666
667
668
669
TEST(NodeTest, DefaultNodeStyle) {
  Node node;
  EXPECT_EQ(EmitterStyle::Default, node.Style());
}

670
671
672
673
674
675
676
TEST(NodeTest, AccessNonexistentKeyOnConstNode) {
  YAML::Node node;
  node["3"] = "4";
  const YAML::Node& other = node;
  ASSERT_FALSE(other["5"]);
}

677
678
679
680
681
682
683
684
class NodeEmitterTest : public ::testing::Test {
 protected:
  void ExpectOutput(const std::string& output, const Node& node) {
    Emitter emitter;
    emitter << node;
    ASSERT_TRUE(emitter.good());
    EXPECT_EQ(output, emitter.c_str());
  }
685
686
687
688
689
690
691
692

  void ExpectAnyOutput(const Node& node, const std::string& output1,
                       const std::string& output2) {
    Emitter emitter;
    emitter << node;
    ASSERT_TRUE(emitter.good());
    EXPECT_THAT(emitter.c_str(), AnyOf(Eq(output1), Eq(output2)));
  }
693
694
695
696
697
};

TEST_F(NodeEmitterTest, SimpleFlowSeqNode) {
  Node node;
  node.SetStyle(EmitterStyle::Flow);
698
699
700
  node.push_back(1.5);
  node.push_back(2.25);
  node.push_back(3.125);
701

702
  ExpectOutput("[1.5, 2.25, 3.125]", node);
703
704
705
706
707
}

TEST_F(NodeEmitterTest, NestFlowSeqNode) {
  Node node, cell0, cell1;

708
709
710
  cell0.push_back(1.5);
  cell0.push_back(2.25);
  cell0.push_back(3.125);
711

712
713
714
  cell1.push_back(4.5);
  cell1.push_back(5.25);
  cell1.push_back(6.125);
715
716
717
718
719

  node.SetStyle(EmitterStyle::Flow);
  node.push_back(cell0);
  node.push_back(cell1);

720
  ExpectOutput("[[1.5, 2.25, 3.125], [4.5, 5.25, 6.125]]", node);
721
722
723
724
725
726
}

TEST_F(NodeEmitterTest, MixBlockFlowSeqNode) {
  Node node, cell0, cell1;

  cell0.SetStyle(EmitterStyle::Flow);
727
728
729
  cell0.push_back(1.5);
  cell0.push_back(2.25);
  cell0.push_back(3.125);
730

731
732
733
  cell1.push_back(4.5);
  cell1.push_back(5.25);
  cell1.push_back(6.125);
734
735
736
737
738

  node.SetStyle(EmitterStyle::Block);
  node.push_back(cell0);
  node.push_back(cell1);

739
  ExpectOutput("- [1.5, 2.25, 3.125]\n-\n  - 4.5\n  - 5.25\n  - 6.125", node);
740
741
742
743
744
}

TEST_F(NodeEmitterTest, NestBlockFlowMapListNode) {
  Node node, mapNode, blockNode;

745
746
747
  node.push_back(1.5);
  node.push_back(2.25);
  node.push_back(3.125);
748
749
750
751

  mapNode.SetStyle(EmitterStyle::Flow);
  mapNode["position"] = node;

752
  blockNode.push_back(1.0625);
753
754
  blockNode.push_back(mapNode);

755
  ExpectOutput("- 1.0625\n- {position: [1.5, 2.25, 3.125]}", blockNode);
756
757
758
759
760
}

TEST_F(NodeEmitterTest, NestBlockMixMapListNode) {
  Node node, mapNode, blockNode;

761
762
763
  node.push_back(1.5);
  node.push_back(2.25);
  node.push_back(3.125);
764
765
766
767

  mapNode.SetStyle(EmitterStyle::Flow);
  mapNode["position"] = node;

768
  blockNode["scalar"] = 1.0625;
769
770
  blockNode["object"] = mapNode;

771
  ExpectAnyOutput(blockNode,
772
773
                  "scalar: 1.0625\nobject: {position: [1.5, 2.25, 3.125]}",
                  "object: {position: [1.5, 2.25, 3.125]}\nscalar: 1.5");
774
775
776
777
778
}

TEST_F(NodeEmitterTest, NestBlockMapListNode) {
  Node node, mapNode;

779
780
781
  node.push_back(1.5);
  node.push_back(2.25);
  node.push_back(3.125);
782
783
784
785

  mapNode.SetStyle(EmitterStyle::Block);
  mapNode["position"] = node;

786
  ExpectOutput("position:\n  - 1.5\n  - 2.25\n  - 3.125", mapNode);
787
788
789
790
791
}

TEST_F(NodeEmitterTest, NestFlowMapListNode) {
  Node node, mapNode;

792
793
794
  node.push_back(1.5);
  node.push_back(2.25);
  node.push_back(3.125);
795
796
797
798

  mapNode.SetStyle(EmitterStyle::Flow);
  mapNode["position"] = node;

799
  ExpectOutput("{position: [1.5, 2.25, 3.125]}", mapNode);
800
}
Jesse Beder's avatar
Jesse Beder committed
801
802
}
}