data_unittests.cc 25.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#include <gtest/gtest.h>
#include <boost/foreach.hpp>
#include <boost/assign/std/vector.hpp>

JINMEI Tatuya's avatar
JINMEI Tatuya committed
19
#include <cc/data.h>
20

Jelte Jansen's avatar
Jelte Jansen committed
21
using namespace isc::data;
22

23
24
25
26
27
#include <iostream>
using std::oct;
#include <iomanip>
using std::setfill;
using std::setw;
28
using std::string;
29

30
namespace {
31
TEST(Element, type) {
32
    // this tests checks whether the getType() function returns the
33
34
    // correct type
    IntElement int_el = IntElement(1);
35
    EXPECT_EQ(int_el.getType(), Element::integer);
36
    DoubleElement double_el = DoubleElement(1.0);
37
    EXPECT_EQ(double_el.getType(), Element::real);
38
    BoolElement bool_el = BoolElement(true);
39
    EXPECT_EQ(bool_el.getType(), Element::boolean);
40
    StringElement str_el = StringElement("foo");
41
    EXPECT_EQ(str_el.getType(), Element::string);
42
    ListElement list_el = ListElement();
43
    EXPECT_EQ(list_el.getType(), Element::list);
44
    MapElement map_el = MapElement();
45
    EXPECT_EQ(map_el.getType(), Element::map);
Jelte Jansen's avatar
Jelte Jansen committed
46

47
48
}

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
TEST(Element, TypeNameConversion) {
    EXPECT_EQ(Element::integer, Element::nameToType("integer"));
    EXPECT_EQ(Element::real, Element::nameToType("real"));
    EXPECT_EQ(Element::boolean, Element::nameToType("boolean"));
    EXPECT_EQ(Element::string, Element::nameToType("string"));
    EXPECT_EQ(Element::list, Element::nameToType("list"));
    EXPECT_EQ(Element::map, Element::nameToType("map"));
    EXPECT_EQ(Element::null, Element::nameToType("null"));
    EXPECT_EQ(Element::any, Element::nameToType("any"));
    EXPECT_THROW(Element::nameToType("somethingunknown"), TypeError);

    EXPECT_EQ("integer", Element::typeToName(Element::integer));
    EXPECT_EQ("real", Element::typeToName(Element::real));
    EXPECT_EQ("boolean", Element::typeToName(Element::boolean));
    EXPECT_EQ("string", Element::typeToName(Element::string));
    EXPECT_EQ("list", Element::typeToName(Element::list));
    EXPECT_EQ("map", Element::typeToName(Element::map));
    EXPECT_EQ("null", Element::typeToName(Element::null));
    EXPECT_EQ("any", Element::typeToName(Element::any));
    EXPECT_EQ("unknown", Element::typeToName((Element::types)123));
}

Jelte Jansen's avatar
Jelte Jansen committed
71
TEST(Element, from_and_to_json) {
72
73
74
    // a set of inputs that are the same when converted to json and
    // back to a string (tests for inputs that have equivalent, but
    // different string representations when converted back are below)
75
    ConstElementPtr el;
76
77
78
79
    std::vector<std::string> sv;

    sv.push_back("12");
    sv.push_back("1.1");
80
81
    sv.push_back("true");
    sv.push_back("false");
82
    sv.push_back("\"asdf\"");
83
    sv.push_back("null");
84
    sv.push_back("[ 1, 2, 3, 4 ]");
85
86
    sv.push_back("{ \"name\": \"foo\", \"value\": 47806 }");
    sv.push_back("[ { \"a\": 1, \"b\": \"c\" }, { \"a\": 2, \"b\": \"d\" } ]");
87
88
89
90
91
92
93
    sv.push_back("8.23");
    sv.push_back("123.456");
    sv.push_back("null");
    sv.push_back("-1");
    sv.push_back("-1.234");
    sv.push_back("-123.456");
    
94
    BOOST_FOREACH(const std::string& s, sv) {
Jelte Jansen's avatar
Jelte Jansen committed
95
        // test << operator, which uses Element::str()
96
        std::ostringstream stream;
97
        el = Element::fromJSON(s);
98
99
        stream << *el;
        EXPECT_EQ(s, stream.str());
Jelte Jansen's avatar
Jelte Jansen committed
100
101
102
103

        // test toWire(ostream), which should also be the same now
        std::ostringstream wire_stream;
        el->toWire(wire_stream);
104
        EXPECT_EQ(s, wire_stream.str());
105
106
107
108
    }

    // some parse errors
    try {
109
        Element::fromJSON("{1}");
110
    } catch (const isc::data::JSONError& pe) {
111
        std::string s = std::string(pe.what());
112
        EXPECT_EQ("String expected in <string>:1:3", s);
113
    }
114
115
116
    
    sv.clear();
    sv.push_back("{1}");
117
    //ElementPtr ep = Element::fromJSON("\"aaa\nbbb\"err");
118
119
120
121
122
123
    //std::cout << ep << std::endl;
    sv.push_back("\n\nTru");
    sv.push_back("{ \n \"aaa\nbbb\"err:");
    sv.push_back("{ \t\n \"aaa\nbbb\"\t\n\n:\n True, \"\\\"");
    sv.push_back("{ \"a\": None}");
    sv.push_back("");
Jelte Jansen's avatar
Jelte Jansen committed
124
    sv.push_back("nul");
125
126
    BOOST_FOREACH(std::string s, sv) {
        
Jelte Jansen's avatar
Jelte Jansen committed
127
        EXPECT_THROW(el = Element::fromJSON(s), isc::data::JSONError);
128
129
    }

130
131
    // some json specific format tests, here the str() output is
    // different from the string input
132
    EXPECT_EQ("100", Element::fromJSON("+100")->str());
133
    EXPECT_EQ("100", Element::fromJSON("1e2")->str());
134
135
    EXPECT_EQ("100", Element::fromJSON("+1e2")->str());
    EXPECT_EQ("-100", Element::fromJSON("-1e2")->str());
136
    EXPECT_EQ("0.01", Element::fromJSON("1e-2")->str());
Jelte Jansen's avatar
Jelte Jansen committed
137
    EXPECT_EQ("0.01", Element::fromJSON(".01")->str());
138
    EXPECT_EQ("-0.01", Element::fromJSON("-1e-2")->str());
139
140
141
142
    EXPECT_EQ("1.2", Element::fromJSON("1.2")->str());
    EXPECT_EQ("1", Element::fromJSON("1.0")->str());
    EXPECT_EQ("120", Element::fromJSON("1.2e2")->str());
    EXPECT_EQ("100", Element::fromJSON("1.0e2")->str());
143
    EXPECT_EQ("100", Element::fromJSON("1.0E2")->str());
144
145
    EXPECT_EQ("0.01", Element::fromJSON("1.0e-2")->str());
    EXPECT_EQ("0.012", Element::fromJSON("1.2e-2")->str());
146
    EXPECT_EQ("0.012", Element::fromJSON("1.2E-2")->str());
147
148
149
150
151
152
    EXPECT_EQ("null", Element::fromJSON("Null")->str());
    EXPECT_EQ("null", Element::fromJSON("NULL")->str());
    EXPECT_EQ("false", Element::fromJSON("False")->str());
    EXPECT_EQ("false", Element::fromJSON("FALSE")->str());
    EXPECT_EQ("true", Element::fromJSON("True")->str());
    EXPECT_EQ("true", Element::fromJSON("TRUE")->str());
Jelte Jansen's avatar
Jelte Jansen committed
153

Jelte Jansen's avatar
Jelte Jansen committed
154
    // number overflows
Jelte Jansen's avatar
Jelte Jansen committed
155
156
    EXPECT_THROW(Element::fromJSON("12345678901234567890")->str(), JSONError);
    EXPECT_THROW(Element::fromJSON("1.1e12345678901234567890")->str(), JSONError);
157
    EXPECT_THROW(Element::fromJSON("-1.1e12345678901234567890")->str(), JSONError);
Jelte Jansen's avatar
Jelte Jansen committed
158
159
160
    EXPECT_THROW(Element::fromJSON("1e12345678901234567890")->str(), JSONError);
    EXPECT_THROW(Element::fromJSON("1e50000")->str(), JSONError);

161
162
163
164
165
166
}

TEST(Element, create_and_value_throws) {
    // this test checks whether elements throw exceptions if the
    // incorrect type is requested
    ElementPtr el;
Jelte Jansen's avatar
Jelte Jansen committed
167
    long int i;
Jelte Jansen's avatar
Jelte Jansen committed
168
169
170
    double d;
    bool b;
    std::string s("asdf");
171
172
    std::vector<ConstElementPtr> v;
    std::map<std::string, ConstElementPtr> m;
173
174

    el = Element::create(1);
175
    EXPECT_NO_THROW(el->intValue());
176
177
178
179
180
    EXPECT_THROW(el->doubleValue(), TypeError);
    EXPECT_THROW(el->boolValue(), TypeError);
    EXPECT_THROW(el->stringValue(), TypeError);
    EXPECT_THROW(el->listValue(), TypeError);
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
    EXPECT_TRUE(el->getValue(i));
    EXPECT_FALSE(el->getValue(d));
    EXPECT_FALSE(el->getValue(b));
    EXPECT_FALSE(el->getValue(s));
    EXPECT_FALSE(el->getValue(v));
    EXPECT_FALSE(el->getValue(m));
    EXPECT_EQ(i, 1);
    i = 2;
    EXPECT_TRUE(el->setValue(i));
    EXPECT_EQ(2, el->intValue());
    EXPECT_FALSE(el->setValue(d));
    EXPECT_FALSE(el->setValue(b));
    EXPECT_FALSE(el->setValue(s));
    EXPECT_FALSE(el->setValue(v));
    EXPECT_FALSE(el->setValue(m));
    EXPECT_THROW(el->get(1), TypeError);
    EXPECT_THROW(el->set(1, el), TypeError);
    EXPECT_THROW(el->add(el), TypeError);
    EXPECT_THROW(el->remove(1), TypeError);
    EXPECT_THROW(el->size(), TypeError);
    EXPECT_THROW(el->get("foo"), TypeError);
    EXPECT_THROW(el->set("foo", el), TypeError);
    EXPECT_THROW(el->remove("foo"), TypeError);
    EXPECT_THROW(el->contains("foo"), TypeError);
205
    ConstElementPtr tmp;
Jelte Jansen's avatar
Jelte Jansen committed
206
207
    EXPECT_FALSE(el->find("foo", tmp));
    
208
209

    el = Element::create(1.1);
210
    EXPECT_THROW(el->intValue(), TypeError);
211
    EXPECT_NO_THROW(el->doubleValue());
212
213
214
215
    EXPECT_THROW(el->boolValue(), TypeError);
    EXPECT_THROW(el->stringValue(), TypeError);
    EXPECT_THROW(el->listValue(), TypeError);
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    EXPECT_FALSE(el->getValue(i));
    EXPECT_TRUE(el->getValue(d));
    EXPECT_FALSE(el->getValue(b));
    EXPECT_FALSE(el->getValue(s));
    EXPECT_FALSE(el->getValue(v));
    EXPECT_FALSE(el->getValue(m));
    EXPECT_EQ(d, 1.1);
    d = 2.2;
    EXPECT_TRUE(el->setValue(d));
    EXPECT_EQ(2.2, el->doubleValue());
    EXPECT_FALSE(el->setValue(i));
    EXPECT_FALSE(el->setValue(b));
    EXPECT_FALSE(el->setValue(s));
    EXPECT_FALSE(el->setValue(v));
    EXPECT_FALSE(el->setValue(m));
231
232

    el = Element::create(true);
233
234
    EXPECT_THROW(el->intValue(), TypeError);
    EXPECT_THROW(el->doubleValue(), TypeError);
235
    EXPECT_NO_THROW(el->boolValue());
236
237
238
    EXPECT_THROW(el->stringValue(), TypeError);
    EXPECT_THROW(el->listValue(), TypeError);
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
239
240
241
242
243
244
245
246
247
    EXPECT_FALSE(el->getValue(i));
    EXPECT_FALSE(el->getValue(d));
    EXPECT_TRUE(el->getValue(b));
    EXPECT_FALSE(el->getValue(s));
    EXPECT_FALSE(el->getValue(v));
    EXPECT_FALSE(el->getValue(m));
    EXPECT_EQ(b, true);
    b = false;
    EXPECT_TRUE(el->setValue(b));
248
    EXPECT_FALSE(el->boolValue());
249
250

    el = Element::create("foo");
251
252
253
    EXPECT_THROW(el->intValue(), TypeError);
    EXPECT_THROW(el->doubleValue(), TypeError);
    EXPECT_THROW(el->boolValue(), TypeError);
254
    EXPECT_NO_THROW(el->stringValue());
255
256
    EXPECT_THROW(el->listValue(), TypeError);
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
257
258
259
260
261
262
263
264
265
266
    EXPECT_FALSE(el->getValue(i));
    EXPECT_FALSE(el->getValue(d));
    EXPECT_FALSE(el->getValue(b));
    EXPECT_TRUE(el->getValue(s));
    EXPECT_FALSE(el->getValue(v));
    EXPECT_FALSE(el->getValue(m));
    EXPECT_EQ(s, "foo");
    s = "bar";
    EXPECT_TRUE(el->setValue(s));
    EXPECT_EQ("bar", el->stringValue());
267

268
    el = Element::createList();
269
270
271
272
    EXPECT_THROW(el->intValue(), TypeError);
    EXPECT_THROW(el->doubleValue(), TypeError);
    EXPECT_THROW(el->boolValue(), TypeError);
    EXPECT_THROW(el->stringValue(), TypeError);
273
    EXPECT_NO_THROW(el->listValue());
274
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
275
276
277
278
279
280
281
282
283
284
    EXPECT_FALSE(el->getValue(i));
    EXPECT_FALSE(el->getValue(d));
    EXPECT_FALSE(el->getValue(b));
    EXPECT_FALSE(el->getValue(s));
    EXPECT_TRUE(el->getValue(v));
    EXPECT_FALSE(el->getValue(m));
    EXPECT_EQ("[  ]", el->str());
    v.push_back(Element::create(1));
    EXPECT_TRUE(el->setValue(v));
    EXPECT_EQ("[ 1 ]", el->str());
285

286
    el = Element::createMap();
287
288
289
290
291
    EXPECT_THROW(el->intValue(), TypeError);
    EXPECT_THROW(el->doubleValue(), TypeError);
    EXPECT_THROW(el->boolValue(), TypeError);
    EXPECT_THROW(el->stringValue(), TypeError);
    EXPECT_THROW(el->listValue(), TypeError);
292
    EXPECT_NO_THROW(el->mapValue());
Jelte Jansen's avatar
Jelte Jansen committed
293
294
295
296
297
298
    EXPECT_FALSE(el->getValue(i));
    EXPECT_FALSE(el->getValue(d));
    EXPECT_FALSE(el->getValue(b));
    EXPECT_FALSE(el->getValue(s));
    EXPECT_FALSE(el->getValue(v));
    EXPECT_TRUE(el->getValue(m));
299
300
301
302
303

}

TEST(Element, ListElement) {
    // this function checks the specific functions for ListElements
304
    ElementPtr el = Element::fromJSON("[ 1, \"bar\", 3 ]");
305
306
307
    EXPECT_EQ(el->get(0)->intValue(), 1);
    EXPECT_EQ(el->get(1)->stringValue(), "bar");
    EXPECT_EQ(el->get(2)->intValue(), 3);
308

309
    el->set(0, Element::fromJSON("\"foo\""));
310
    EXPECT_EQ(el->get(0)->stringValue(), "foo");
311
312

    el->add(Element::create(47806));
313
    EXPECT_EQ(el->get(3)->intValue(), 47806);
314
315
316
317
318
319
320
321
322

    el->remove(1);
    el->remove(1);
    EXPECT_EQ(el->str(), "[ \"foo\", 47806 ]");

    // hmm, it errors on EXPECT_THROW(el->get(3), std::out_of_range)
    EXPECT_ANY_THROW(el->get(3));

    el->add(Element::create(32));
323
324
325
326
327
328
329
    EXPECT_EQ(32, el->get(2)->intValue());

    // boundary condition tests for set()
    el->set(2, Element::create(0)); // update the last entry of the list
    EXPECT_EQ(0, el->get(2)->intValue());
    // attempt of set beyond the range of list should trigger an exception.
    EXPECT_ANY_THROW(el->set(3, Element::create(0)));
330
331
332
333
}

TEST(Element, MapElement) {
    // this function checks the specific functions for ListElements
334
    ElementPtr el = Element::fromJSON("{ \"name\": \"foo\", \"value1\": \"bar\", \"value2\": { \"number\": 42 } }");
335
    ConstElementPtr el2;
336
    
337
338
    EXPECT_EQ(el->get("name")->stringValue(), "foo");
    EXPECT_EQ(el->get("value2")->getType(), Element::map);
339

340
    EXPECT_TRUE(isNull(el->get("value3")));
341
342

    el->set("value3", Element::create(47806));
343
    EXPECT_EQ(el->get("value3")->intValue(), 47806);
344
345

    el->remove("value3");
346
    EXPECT_TRUE(isNull(el->get("value3")));
347

348
    EXPECT_EQ(el->find("value2/number")->intValue(), 42);
349
    EXPECT_TRUE(isNull(el->find("value2/nothing/")));
350
   
351
352
    EXPECT_EQ(el->find("value1")->stringValue(), "bar");
    EXPECT_EQ(el->find("value1/")->stringValue(), "bar");
353
354
355
    
    EXPECT_TRUE(el->find("value1", el2));
    EXPECT_FALSE(el->find("name/error", el2));
356
357
358
359
360
361
362
363

    // A map element whose (only) element has the maximum length of tag.
    string long_maptag("0123456789abcdef1123456789abcdef2123456789abcdef"
                       "3123456789abcdef4123456789abcdef5123456789abcdef"
                       "6123456789abcdef7123456789abcdef8123456789abcdef"
                       "9123456789abcdefa123456789abcdefb123456789abcdef"
                       "c123456789abcdefd123456789abcdefe123456789abcdef"
                       "f123456789abcde");
364
    
365
    EXPECT_EQ(255, long_maptag.length()); // check prerequisite
366
    el = Element::fromJSON("{ \"" + long_maptag + "\": \"bar\"}");
367
368
    EXPECT_EQ("bar", el->find(long_maptag)->stringValue());

369
370
    el = Element::createMap();
    el->set(long_maptag, Element::create("bar"));
371
372
    EXPECT_EQ("bar", el->find(long_maptag)->stringValue());

373
    // A one-byte longer tag should still be allowed
374
    long_maptag.push_back('f');
375
376
377
    el = Element::fromJSON("{ \"" + long_maptag + "\": \"bar\"}");
    el->set(long_maptag, Element::create("bar"));
    EXPECT_EQ("bar", el->find(long_maptag)->stringValue());
378

379
380
381
}

TEST(Element, to_and_from_wire) {
382
383
384
385
386
387
388
    // Wire format is now plain JSON.
    EXPECT_EQ("1", Element::create(1)->toWire());
    EXPECT_EQ("1.1", Element::create(1.1)->toWire());
    EXPECT_EQ("true", Element::create(true)->toWire());
    EXPECT_EQ("false", Element::create(false)->toWire());
    EXPECT_EQ("null", Element::create()->toWire());
    EXPECT_EQ("\"a string\"", Element::create("a string")->toWire());
389
390
    EXPECT_EQ("[ \"a\", \"list\" ]", Element::fromJSON("[ \"a\", \"list\" ]")->toWire());
    EXPECT_EQ("{ \"a\": \"map\" }", Element::fromJSON("{ \"a\": \"map\" }")->toWire());
391
392

    EXPECT_EQ("1", Element::fromWire("1")->str());
Jelte Jansen's avatar
Jelte Jansen committed
393
394
395
396

    std::stringstream ss;
    ss << "1";
    EXPECT_EQ("1", Element::fromWire(ss, 1)->str());
397
398

    // Some malformed JSON input
399
400
401
402
403
404
405
406
    EXPECT_THROW(Element::fromJSON("{ "), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("{ \"a\" "), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("{ \"a\": "), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("{ \"a\": \"b\""), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("{ \"a\": {"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("{ \"a\": {}"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("{ \"a\": []"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("{ \"a\": [ }"), isc::data::JSONError);
407
408
409
    EXPECT_THROW(Element::fromJSON("{\":"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("]"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("[ 1, 2, }"), isc::data::JSONError);
410
411
    EXPECT_THROW(Element::fromJSON("[ 1, 2, {}"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("[ 1, 2, { ]"), isc::data::JSONError);
Jelte Jansen's avatar
Jelte Jansen committed
412
413
414
415
416
    EXPECT_THROW(Element::fromJSON("[ "), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("{{}}"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("{[]}"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("{ \"a\", \"b\" }"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("[ \"a\": \"b\" ]"), isc::data::JSONError);
417
418
}

419
ConstElementPtr
420
efs(const std::string& str) {
JINMEI Tatuya's avatar
JINMEI Tatuya committed
421
    return (Element::fromJSON(str));
422
423
424
}

TEST(Element, equals) {
425
426
427
428
429
430
431
432
433
434
435
436
437
438
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
467
468
469
470
471
472
473
474
    EXPECT_EQ(*efs("1"), *efs("1"));
    EXPECT_NE(*efs("1"), *efs("2"));
    EXPECT_NE(*efs("1"), *efs("\"1\""));
    EXPECT_NE(*efs("1"), *efs("[]"));
    EXPECT_NE(*efs("1"), *efs("True"));
    EXPECT_NE(*efs("1"), *efs("{}"));

    EXPECT_EQ(*efs("1.1"), *efs("1.1"));
    EXPECT_NE(*efs("1.0"), *efs("1"));
    EXPECT_NE(*efs("1.1"), *efs("\"1\""));
    EXPECT_NE(*efs("1.1"), *efs("[]"));
    EXPECT_NE(*efs("1.1"), *efs("True"));
    EXPECT_NE(*efs("1.1"), *efs("{}"));

    EXPECT_EQ(*efs("True"), *efs("True"));
    EXPECT_NE(*efs("True"), *efs("False"));
    EXPECT_NE(*efs("True"), *efs("1"));
    EXPECT_NE(*efs("True"), *efs("\"1\""));
    EXPECT_NE(*efs("True"), *efs("[]"));
    EXPECT_NE(*efs("True"), *efs("{}"));

    EXPECT_EQ(*efs("\"foo\""), *efs("\"foo\""));
    EXPECT_NE(*efs("\"foo\""), *efs("\"bar\""));
    EXPECT_NE(*efs("\"foo\""), *efs("1"));
    EXPECT_NE(*efs("\"foo\""), *efs("\"1\""));
    EXPECT_NE(*efs("\"foo\""), *efs("True"));
    EXPECT_NE(*efs("\"foo\""), *efs("[]"));
    EXPECT_NE(*efs("\"foo\""), *efs("{}"));

    EXPECT_EQ(*efs("[]"), *efs("[]"));
    EXPECT_EQ(*efs("[ 1, 2, 3 ]"), *efs("[ 1, 2, 3 ]"));
    EXPECT_EQ(*efs("[ \"a\", [ True, 1], 2.2 ]"), *efs("[ \"a\", [ True, 1], 2.2 ]"));
    EXPECT_NE(*efs("[ \"a\", [ True, 1], 2.2 ]"), *efs("[ \"a\", [ True, 2], 2.2 ]"));
    EXPECT_NE(*efs("[]"), *efs("[1]"));
    EXPECT_NE(*efs("[]"), *efs("1"));
    EXPECT_NE(*efs("[]"), *efs("\"1\""));
    EXPECT_NE(*efs("[]"), *efs("{}"));

    EXPECT_EQ(*efs("{}"), *efs("{}"));
    EXPECT_EQ(*efs("{ \"foo\": \"bar\" }"), *efs("{ \"foo\": \"bar\" }"));
    EXPECT_EQ(*efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }"), *efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }"));
    EXPECT_NE(*efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }"), *efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar2\" } }"));
    EXPECT_NE(*efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\" ], \"item3\": { \"foo\": \"bar\" } }"), *efs("{ \"item1\": 1, \"item2\": [ \"a\", \"list\", 1 ], \"item3\": { \"foo\": \"bar\" } }"));
    EXPECT_NE(*efs("{ \"foo\": \"bar\" }"), *efs("1"));
    EXPECT_NE(*efs("{ \"foo\": \"bar\" }"), *efs("\"1\""));
    EXPECT_NE(*efs("{ \"foo\": \"bar\" }"), *efs("[]"));
    EXPECT_NE(*efs("{ \"foo\": \"bar\" }"), *efs("{}"));
    EXPECT_NE(*efs("{ \"foo\": \"bar\" }"), *efs("{ \"something\": \"different\" }"));

    EXPECT_EQ(*efs("null"), *Element::create());
475
476
477
}

TEST(Element, removeIdentical) {
478
    ElementPtr a = Element::createMap();
479
480
    ConstElementPtr b = Element::createMap();
    ConstElementPtr c = Element::createMap();
481
    removeIdentical(a, b);
482
    EXPECT_EQ(*a, *c);
483

484
485
    a = Element::fromJSON("{ \"a\": 1 }");
    b = Element::fromJSON("{ \"a\": 1 }");
486
    c = Element::createMap();
487
    removeIdentical(a, b);
488
    EXPECT_EQ(*a, *c);
489

490
    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
491
    b = Element::createMap();
492
    c = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
493
    removeIdentical(a, b);
494
    EXPECT_EQ(*a, *c);
495

496
497
    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
    b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
498
    c = Element::createMap();
499
    removeIdentical(a, b);
500
    EXPECT_EQ(*a, *c);
501

502
503
504
    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
    b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 3 ] }");
    c = Element::fromJSON("{ \"b\": [ 1, 2 ] }");
505
    removeIdentical(a, b);
506
    EXPECT_EQ(*a, *c);
507

508
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
509
    b = Element::createMap();
510
    c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
511
    removeIdentical(a, b);
512
    EXPECT_EQ(*a, *c);
513

514
515
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
516
    c = Element::createMap();
517
    removeIdentical(a, b);
518
    EXPECT_EQ(*a, *c);
519

520
521
522
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
523
    removeIdentical(a, b);
524
    EXPECT_EQ(*a, *c);
Jelte Jansen's avatar
Jelte Jansen committed
525

526
527
528
529
530
531
    a = Element::fromJSON("{ \"a\": 1, \"b\": 2, \"c\": 3 }");
    b = Element::fromJSON("{ \"c\": 3, \"b\": 2 }");
    c = Element::fromJSON("{ \"a\": 1 }");
    removeIdentical(a, b);
    EXPECT_EQ(*a, *c);

Jelte Jansen's avatar
Jelte Jansen committed
532
    EXPECT_THROW(removeIdentical(Element::create(1), Element::create(2)), TypeError);
533
}
534

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
TEST(Element, constRemoveIdentical) {
    ConstElementPtr a = Element::createMap();
    ConstElementPtr b = Element::createMap();
    ConstElementPtr c = Element::createMap();
    EXPECT_EQ(*removeIdentical(a, b), *c);

    a = Element::fromJSON("{ \"a\": 1 }");
    b = Element::fromJSON("{ \"a\": 1 }");
    c = Element::createMap();
    EXPECT_EQ(*removeIdentical(a, b), *c);

    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
    b = Element::createMap();
    c = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
    EXPECT_EQ(*removeIdentical(a, b), *c);

    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
    b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
    c = Element::createMap();
    EXPECT_EQ(*removeIdentical(a, b), *c);

    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
    b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 3 ] }");
    c = Element::fromJSON("{ \"b\": [ 1, 2 ] }");
    EXPECT_EQ(*removeIdentical(a, b), *c);

    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::createMap();
    c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    EXPECT_EQ(*removeIdentical(a, b), *c);

    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    c = Element::createMap();
    EXPECT_EQ(*removeIdentical(a, b), *c);

    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    EXPECT_EQ(*removeIdentical(a, b), *c);

576
577
578
579
580
    a = Element::fromJSON("{ \"a\": 1, \"b\": 2, \"c\": 3 }");
    b = Element::fromJSON("{ \"c\": 3, \"b\": 2 }");
    c = Element::fromJSON("{ \"a\": 1 }");
    EXPECT_EQ(*removeIdentical(a, b), *c);

581
582
583
584
585
    EXPECT_THROW(removeIdentical(Element::create(1), Element::create(2)),
                 TypeError);
}

TEST(Element, merge) {
586
587
    ElementPtr a = Element::createMap();
    ElementPtr b = Element::createMap();
588
    ConstElementPtr c = Element::createMap();
589
    merge(a, b);
590
    EXPECT_EQ(*a, *c);
591

592
    a = Element::fromJSON("1");
593
    b = Element::createMap();
594
595
    EXPECT_THROW(merge(a, b), TypeError);

596
    a = Element::createMap();
597
598
    b = Element::fromJSON("{ \"a\": 1 }");
    c = Element::fromJSON("{ \"a\": 1 }");
599
    merge(a, b);
600
    EXPECT_EQ(*a, *c);
601
602
603
604
605

    a = Element::createMap();
    b = Element::fromJSON("{ \"a\": 1 }");
    c = Element::fromJSON("{ \"a\": 1 }");
    merge(b, a);
606
    EXPECT_EQ(*b, *c);
607

608
609
610
    a = Element::fromJSON("{ \"a\": 1 }");
    b = Element::fromJSON("{ \"a\": 2 }");
    c = Element::fromJSON("{ \"a\": 2 }");
611
    merge(a, b);
612
    EXPECT_EQ(*a, *c);
613
614
615
616
617

    a = Element::fromJSON("{ \"a\": 1 }");
    b = Element::fromJSON("{ \"a\": 2 }");
    c = Element::fromJSON("{ \"a\": 1 }");
    merge(b, a);
618
    EXPECT_EQ(*b, *c);
619

620
621
622
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
623
    merge(a, b);
624
    EXPECT_EQ(*a, *c);
625
626
627
628
629

    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    merge(b, a);
630
    EXPECT_EQ(*b, *c);
631

Jelte Jansen's avatar
Jelte Jansen committed
632
633
634
635
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": null }");
    c = Element::fromJSON("{  }");
    merge(a, b);
636
    EXPECT_EQ(*a, *c);
637
638
639
640
641

    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": null }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    merge(b, a);
642
    EXPECT_EQ(*b, *c);
643
644
645
646
647
648
    
    // And some tests with multiple values
    a = Element::fromJSON("{ \"a\": 1, \"b\": true, \"c\": null }");
    b = Element::fromJSON("{ \"a\": 1, \"b\": null, \"c\": \"a string\" }");
    c = Element::fromJSON("{ \"a\": 1, \"c\": \"a string\" }");
    merge(a, b);
649
    EXPECT_EQ(*a, *c);
650
651
652
653
654

    a = Element::fromJSON("{ \"a\": 1, \"b\": true, \"c\": null }");
    b = Element::fromJSON("{ \"a\": 1, \"b\": null, \"c\": \"a string\" }");
    c = Element::fromJSON("{ \"a\": 1, \"b\": true }");
    merge(b, a);
655
    EXPECT_EQ(*b, *c);
656
657
658
659
660

    a = Element::fromJSON("{ \"a\": 1, \"b\": 2, \"c\": 3 }");
    b = Element::fromJSON("{ \"a\": 3, \"b\": 2, \"c\": 1 }");
    c = Element::fromJSON("{ \"a\": 3, \"b\": 2, \"c\": 1 }");
    merge(a, b);
661
    EXPECT_EQ(*a, *c);
662
663
664
665
666

    a = Element::fromJSON("{ \"a\": 1, \"b\": 2, \"c\": 3 }");
    b = Element::fromJSON("{ \"a\": 3, \"b\": 2, \"c\": 1 }");
    c = Element::fromJSON("{ \"a\": 1, \"b\": 2, \"c\": 3 }");
    merge(b, a);
667
    EXPECT_EQ(*b, *c);
Jelte Jansen's avatar
Jelte Jansen committed
668

669
}
670
}