data_unittests.cc 27.6 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
#include <sstream>
24
25
26
27
28
#include <iostream>
using std::oct;
#include <iomanip>
using std::setfill;
using std::setw;
29
using std::string;
30

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

48
49
}

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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
72
TEST(Element, from_and_to_json) {
73
74
75
    // 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)
76
    ConstElementPtr el;
77
78
79
80
    std::vector<std::string> sv;

    sv.push_back("12");
    sv.push_back("1.1");
81
82
    sv.push_back("true");
    sv.push_back("false");
83
    sv.push_back("\"asdf\"");
84
    sv.push_back("null");
85
    sv.push_back("[ 1, 2, 3, 4 ]");
86
87
    sv.push_back("{ \"name\": \"foo\", \"value\": 47806 }");
    sv.push_back("[ { \"a\": 1, \"b\": \"c\" }, { \"a\": 2, \"b\": \"d\" } ]");
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

95
    BOOST_FOREACH(const std::string& s, sv) {
Jelte Jansen's avatar
Jelte Jansen committed
96
        // test << operator, which uses Element::str()
97
        std::ostringstream stream;
98
        el = Element::fromJSON(s);
99
100
        stream << *el;
        EXPECT_EQ(s, stream.str());
Jelte Jansen's avatar
Jelte Jansen committed
101
102
103
104

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

    // some parse errors
    try {
110
        Element::fromJSON("{1}");
111
    } catch (const isc::data::JSONError& pe) {
112
        std::string s = std::string(pe.what());
113
        EXPECT_EQ("String expected in <string>:1:3", s);
114
    }
115

116
117
    sv.clear();
    sv.push_back("{1}");
118
    //ElementPtr ep = Element::fromJSON("\"aaa\nbbb\"err");
119
120
121
122
123
124
    //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
125
    sv.push_back("nul");
126
127
128
129
    sv.push_back("hello\"foobar\"");
    sv.push_back("\"foobar\"hello");
    sv.push_back("[]hello");
    sv.push_back("{}hello");
130
131
132
133
134
    // String not delimited correctly
    sv.push_back("\"hello");
    sv.push_back("hello\"");


135
    BOOST_FOREACH(std::string s, sv) {
Jelte Jansen's avatar
Jelte Jansen committed
136
        EXPECT_THROW(el = Element::fromJSON(s), isc::data::JSONError);
137
138
    }

139
140
    // some json specific format tests, here the str() output is
    // different from the string input
141
    EXPECT_EQ("100", Element::fromJSON("+100")->str());
142
    EXPECT_EQ("100", Element::fromJSON("1e2")->str());
143
144
    EXPECT_EQ("100", Element::fromJSON("+1e2")->str());
    EXPECT_EQ("-100", Element::fromJSON("-1e2")->str());
145
    EXPECT_EQ("0.01", Element::fromJSON("1e-2")->str());
Jelte Jansen's avatar
Jelte Jansen committed
146
    EXPECT_EQ("0.01", Element::fromJSON(".01")->str());
147
    EXPECT_EQ("-0.01", Element::fromJSON("-1e-2")->str());
148
149
150
151
    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());
152
    EXPECT_EQ("100", Element::fromJSON("1.0E2")->str());
153
154
    EXPECT_EQ("0.01", Element::fromJSON("1.0e-2")->str());
    EXPECT_EQ("0.012", Element::fromJSON("1.2e-2")->str());
155
    EXPECT_EQ("0.012", Element::fromJSON("1.2E-2")->str());
156
157
158
159
160
161
    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());
162
163
164
    EXPECT_EQ("\"\"", Element::fromJSON("  \n \t \r \f \b \"\" \n \f \t \r \b")->str());
    EXPECT_EQ("{  }", Element::fromJSON("{  \n  \r \t  \b \f }")->str());
    EXPECT_EQ("[  ]", Element::fromJSON("[  \n  \r \f \t  \b  ]")->str());
Jelte Jansen's avatar
Jelte Jansen committed
165

Jelte Jansen's avatar
Jelte Jansen committed
166
    // number overflows
Jelte Jansen's avatar
Jelte Jansen committed
167
168
    EXPECT_THROW(Element::fromJSON("12345678901234567890")->str(), JSONError);
    EXPECT_THROW(Element::fromJSON("1.1e12345678901234567890")->str(), JSONError);
169
    EXPECT_THROW(Element::fromJSON("-1.1e12345678901234567890")->str(), JSONError);
Jelte Jansen's avatar
Jelte Jansen committed
170
171
172
    EXPECT_THROW(Element::fromJSON("1e12345678901234567890")->str(), JSONError);
    EXPECT_THROW(Element::fromJSON("1e50000")->str(), JSONError);

173
174
175
176
177
178
}

TEST(Element, create_and_value_throws) {
    // this test checks whether elements throw exceptions if the
    // incorrect type is requested
    ElementPtr el;
179
    ConstElementPtr cel;
Jelte Jansen's avatar
Jelte Jansen committed
180
    long int i;
Jelte Jansen's avatar
Jelte Jansen committed
181
182
183
    double d;
    bool b;
    std::string s("asdf");
184
185
    std::vector<ConstElementPtr> v;
    std::map<std::string, ConstElementPtr> m;
186
187

    el = Element::create(1);
188
    EXPECT_NO_THROW(el->intValue());
189
190
191
192
193
    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
194
195
196
197
198
199
200
    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);
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

    cel = Element::create(1);
    EXPECT_NO_THROW(cel->intValue());
    EXPECT_THROW(cel->doubleValue(), TypeError);
    EXPECT_THROW(cel->boolValue(), TypeError);
    EXPECT_THROW(cel->stringValue(), TypeError);
    EXPECT_THROW(cel->listValue(), TypeError);
    EXPECT_THROW(cel->mapValue(), TypeError);
    EXPECT_TRUE(cel->getValue(i));
    EXPECT_FALSE(cel->getValue(d));
    EXPECT_FALSE(cel->getValue(b));
    EXPECT_FALSE(cel->getValue(s));
    EXPECT_FALSE(cel->getValue(v));
    EXPECT_FALSE(cel->getValue(m));
    EXPECT_EQ(i, 1);

Jelte Jansen's avatar
Jelte Jansen committed
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
    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);
234
    ConstElementPtr tmp;
Jelte Jansen's avatar
Jelte Jansen committed
235
    EXPECT_FALSE(el->find("foo", tmp));
236

237
238

    el = Element::create(1.1);
239
    EXPECT_THROW(el->intValue(), TypeError);
240
    EXPECT_NO_THROW(el->doubleValue());
241
242
243
244
    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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    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));
260
261

    el = Element::create(true);
262
263
    EXPECT_THROW(el->intValue(), TypeError);
    EXPECT_THROW(el->doubleValue(), TypeError);
264
    EXPECT_NO_THROW(el->boolValue());
265
266
267
    EXPECT_THROW(el->stringValue(), TypeError);
    EXPECT_THROW(el->listValue(), TypeError);
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
268
269
270
271
272
273
274
275
276
    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));
277
    EXPECT_FALSE(el->boolValue());
278
279

    el = Element::create("foo");
280
281
282
    EXPECT_THROW(el->intValue(), TypeError);
    EXPECT_THROW(el->doubleValue(), TypeError);
    EXPECT_THROW(el->boolValue(), TypeError);
283
    EXPECT_NO_THROW(el->stringValue());
284
285
    EXPECT_THROW(el->listValue(), TypeError);
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
286
287
288
289
290
291
292
293
294
295
    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());
296

297
    el = Element::createList();
298
299
300
301
    EXPECT_THROW(el->intValue(), TypeError);
    EXPECT_THROW(el->doubleValue(), TypeError);
    EXPECT_THROW(el->boolValue(), TypeError);
    EXPECT_THROW(el->stringValue(), TypeError);
302
    EXPECT_NO_THROW(el->listValue());
303
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
304
305
306
307
308
309
310
311
312
313
    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());
314

315
    el = Element::createMap();
316
317
318
319
320
    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);
321
    EXPECT_NO_THROW(el->mapValue());
Jelte Jansen's avatar
Jelte Jansen committed
322
323
324
325
326
327
    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));
328
329
330

}

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
// Helper for escape check; it puts the given string in a StringElement,
// then checks for the following conditions:
// stringValue() must be same as input
// toJSON() output must be escaped
// fromJSON() on the previous output must result in original input
void
escapeHelper(const std::string& input, const std::string& expected) {
    StringElement str_element = StringElement(input);
    EXPECT_EQ(input, str_element.stringValue());
    std::stringstream os;
    str_element.toJSON(os);
    EXPECT_EQ(expected, os.str());
    ElementPtr str_element2 = Element::fromJSON(os.str());
    EXPECT_EQ(str_element.stringValue(), str_element2->stringValue());
}

TEST(Element, escape) {
    // Test whether quotes are escaped correctly when creating direct
    // String elements.
    escapeHelper("foo\"bar", "\"foo\\\"bar\"");
    escapeHelper("foo\\bar", "\"foo\\\\bar\"");
352
353
354
355
356
    escapeHelper("foo\bbar", "\"foo\\bbar\"");
    escapeHelper("foo\fbar", "\"foo\\fbar\"");
    escapeHelper("foo\nbar", "\"foo\\nbar\"");
    escapeHelper("foo\rbar", "\"foo\\rbar\"");
    escapeHelper("foo\tbar", "\"foo\\tbar\"");
357
358
359
    // Bad escapes
    EXPECT_THROW(Element::fromJSON("\\a"), JSONError);
    EXPECT_THROW(Element::fromJSON("\\"), JSONError);
360
361
362
363
364
    // Can't have escaped quotes outside strings
    EXPECT_THROW(Element::fromJSON("\\\"\\\""), JSONError);
    // Inside strings is OK
    EXPECT_NO_THROW(Element::fromJSON("\"\\\"\\\"\""));
    // A whitespace test
Mukund Sivaraman's avatar
Mukund Sivaraman committed
365
    EXPECT_NO_THROW(Element::fromJSON("\"  \n  \r \t \f  \n \n    \t\""));
366
367
}

368
369
TEST(Element, ListElement) {
    // this function checks the specific functions for ListElements
370
    ElementPtr el = Element::fromJSON("[ 1, \"bar\", 3 ]");
371
372
373
    EXPECT_EQ(el->get(0)->intValue(), 1);
    EXPECT_EQ(el->get(1)->stringValue(), "bar");
    EXPECT_EQ(el->get(2)->intValue(), 3);
374

375
    el->set(0, Element::fromJSON("\"foo\""));
376
    EXPECT_EQ(el->get(0)->stringValue(), "foo");
377
378

    el->add(Element::create(47806));
379
    EXPECT_EQ(el->get(3)->intValue(), 47806);
380
381
382
383
384
385
386
387
388

    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));
389
390
391
392
393
394
395
    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)));
396
397
398
399
}

TEST(Element, MapElement) {
    // this function checks the specific functions for ListElements
400
    ElementPtr el = Element::fromJSON("{ \"name\": \"foo\", \"value1\": \"bar\", \"value2\": { \"number\": 42 } }");
401
    ConstElementPtr el2;
402

403
404
    EXPECT_EQ(el->get("name")->stringValue(), "foo");
    EXPECT_EQ(el->get("value2")->getType(), Element::map);
405

406
    EXPECT_TRUE(isNull(el->get("value3")));
407
408

    el->set("value3", Element::create(47806));
409
    EXPECT_EQ(el->get("value3")->intValue(), 47806);
410
411

    el->remove("value3");
412
    EXPECT_TRUE(isNull(el->get("value3")));
413

414
    EXPECT_EQ(el->find("value2/number")->intValue(), 42);
415
    EXPECT_TRUE(isNull(el->find("value2/nothing/")));
416

417
418
    EXPECT_EQ(el->find("value1")->stringValue(), "bar");
    EXPECT_EQ(el->find("value1/")->stringValue(), "bar");
419

420
    EXPECT_TRUE(el->find("value1", el2));
421
    EXPECT_EQ("bar", el2->stringValue());
422
    EXPECT_FALSE(el->find("name/error", el2));
423
424
425
426
427
428
429
430

    // A map element whose (only) element has the maximum length of tag.
    string long_maptag("0123456789abcdef1123456789abcdef2123456789abcdef"
                       "3123456789abcdef4123456789abcdef5123456789abcdef"
                       "6123456789abcdef7123456789abcdef8123456789abcdef"
                       "9123456789abcdefa123456789abcdefb123456789abcdef"
                       "c123456789abcdefd123456789abcdefe123456789abcdef"
                       "f123456789abcde");
431

432
    EXPECT_EQ(255, long_maptag.length()); // check prerequisite
433
    el = Element::fromJSON("{ \"" + long_maptag + "\": \"bar\"}");
434
435
    EXPECT_EQ("bar", el->find(long_maptag)->stringValue());

436
437
    el = Element::createMap();
    el->set(long_maptag, Element::create("bar"));
438
439
    EXPECT_EQ("bar", el->find(long_maptag)->stringValue());

440
    // A one-byte longer tag should still be allowed
441
    long_maptag.push_back('f');
442
443
444
    el = Element::fromJSON("{ \"" + long_maptag + "\": \"bar\"}");
    el->set(long_maptag, Element::create("bar"));
    EXPECT_EQ("bar", el->find(long_maptag)->stringValue());
445

446
447
448
}

TEST(Element, to_and_from_wire) {
449
450
451
452
453
454
455
    // 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());
456
457
    EXPECT_EQ("[ \"a\", \"list\" ]", Element::fromJSON("[ \"a\", \"list\" ]")->toWire());
    EXPECT_EQ("{ \"a\": \"map\" }", Element::fromJSON("{ \"a\": \"map\" }")->toWire());
458
459

    EXPECT_EQ("1", Element::fromWire("1")->str());
Jelte Jansen's avatar
Jelte Jansen committed
460
461
462
463

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

    // Some malformed JSON input
466
467
468
469
470
471
472
473
    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);
474
475
476
    EXPECT_THROW(Element::fromJSON("{\":"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("]"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("[ 1, 2, }"), isc::data::JSONError);
477
478
    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
479
480
481
482
483
    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);
484
485
}

486
ConstElementPtr
487
efs(const std::string& str) {
JINMEI Tatuya's avatar
JINMEI Tatuya committed
488
    return (Element::fromJSON(str));
489
490
491
}

TEST(Element, equals) {
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
    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());
542
543
544
}

TEST(Element, removeIdentical) {
545
    ElementPtr a = Element::createMap();
546
547
    ConstElementPtr b = Element::createMap();
    ConstElementPtr c = Element::createMap();
548
    removeIdentical(a, b);
549
    EXPECT_EQ(*a, *c);
550

551
552
    a = Element::fromJSON("{ \"a\": 1 }");
    b = Element::fromJSON("{ \"a\": 1 }");
553
    c = Element::createMap();
554
    removeIdentical(a, b);
555
    EXPECT_EQ(*a, *c);
556

557
    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
558
    b = Element::createMap();
559
    c = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
560
    removeIdentical(a, b);
561
    EXPECT_EQ(*a, *c);
562

563
564
    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
    b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
565
    c = Element::createMap();
566
    removeIdentical(a, b);
567
    EXPECT_EQ(*a, *c);
568

569
570
571
    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
    b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 3 ] }");
    c = Element::fromJSON("{ \"b\": [ 1, 2 ] }");
572
    removeIdentical(a, b);
573
    EXPECT_EQ(*a, *c);
574

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

581
582
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
583
    c = Element::createMap();
584
    removeIdentical(a, b);
585
    EXPECT_EQ(*a, *c);
586

587
588
589
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
590
    removeIdentical(a, b);
591
    EXPECT_EQ(*a, *c);
Jelte Jansen's avatar
Jelte Jansen committed
592

593
594
595
596
597
598
    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
599
    EXPECT_THROW(removeIdentical(Element::create(1), Element::create(2)), TypeError);
600
}
601

602
603
604
605
606
607
608
609
610
611
612
613
614
615
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(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);

643
644
645
646
647
    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);

648
649
650
651
652
    EXPECT_THROW(removeIdentical(Element::create(1), Element::create(2)),
                 TypeError);
}

TEST(Element, merge) {
653
654
    ElementPtr a = Element::createMap();
    ElementPtr b = Element::createMap();
655
    ConstElementPtr c = Element::createMap();
656
    merge(a, b);
657
    EXPECT_EQ(*a, *c);
658

659
    a = Element::fromJSON("1");
660
    b = Element::createMap();
661
662
    EXPECT_THROW(merge(a, b), TypeError);

663
    a = Element::createMap();
664
665
    b = Element::fromJSON("{ \"a\": 1 }");
    c = Element::fromJSON("{ \"a\": 1 }");
666
    merge(a, b);
667
    EXPECT_EQ(*a, *c);
668
669
670
671
672

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

675
676
677
    a = Element::fromJSON("{ \"a\": 1 }");
    b = Element::fromJSON("{ \"a\": 2 }");
    c = Element::fromJSON("{ \"a\": 2 }");
678
    merge(a, b);
679
    EXPECT_EQ(*a, *c);
680
681
682
683
684

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

687
688
689
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
690
    merge(a, b);
691
    EXPECT_EQ(*a, *c);
692
693
694
695
696

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

Jelte Jansen's avatar
Jelte Jansen committed
699
700
701
702
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": null }");
    c = Element::fromJSON("{  }");
    merge(a, b);
703
    EXPECT_EQ(*a, *c);
704
705
706
707
708

    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": null }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    merge(b, a);
709
    EXPECT_EQ(*b, *c);
710

711
712
713
714
715
    // 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);
716
    EXPECT_EQ(*a, *c);
717
718
719
720
721

    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);
722
    EXPECT_EQ(*b, *c);
723
724
725
726
727

    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);
728
    EXPECT_EQ(*a, *c);
729
730
731
732
733

    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);
734
    EXPECT_EQ(*b, *c);
Jelte Jansen's avatar
Jelte Jansen committed
735

736
}
737
}