data_unittests.cc 21.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// 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.

// $Id$

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

#include <data.h>

Jelte Jansen's avatar
Jelte Jansen committed
23
using namespace isc::data;
24

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

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 77 78 79 80
    ElementPtr el;
    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 94
    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");
    
95
    BOOST_FOREACH(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(stream.str(), s);
Jelte Jansen's avatar
Jelte Jansen committed
101 102 103 104 105

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

    // some parse errors
    try {
110
        Element::fromJSON("{1}");
Jelte Jansen's avatar
Jelte Jansen committed
111
    } catch (isc::data::JSONError pe) {
112
        std::string s = std::string(pe.what());
113
        EXPECT_EQ(s, "String expected in <string>:1:3");
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
    BOOST_FOREACH(std::string s, sv) {
        
Jelte Jansen's avatar
Jelte Jansen committed
128
        EXPECT_THROW(el = Element::fromJSON(s), isc::data::JSONError);
129 130
    }

131 132
    // some json specific format tests, here the str() output is
    // different from the string input
133
    EXPECT_EQ("100", Element::fromJSON("+100")->str());
134
    EXPECT_EQ("100", Element::fromJSON("1e2")->str());
135 136
    EXPECT_EQ("100", Element::fromJSON("+1e2")->str());
    EXPECT_EQ("-100", Element::fromJSON("-1e2")->str());
137
    EXPECT_EQ("0.01", Element::fromJSON("1e-2")->str());
Jelte Jansen's avatar
Jelte Jansen committed
138
    EXPECT_EQ("0.01", Element::fromJSON(".01")->str());
139
    EXPECT_EQ("-0.01", Element::fromJSON("-1e-2")->str());
140 141 142 143
    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());
144
    EXPECT_EQ("100", Element::fromJSON("1.0E2")->str());
145 146
    EXPECT_EQ("0.01", Element::fromJSON("1.0e-2")->str());
    EXPECT_EQ("0.012", Element::fromJSON("1.2e-2")->str());
147
    EXPECT_EQ("0.012", Element::fromJSON("1.2E-2")->str());
148 149 150 151 152 153
    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
154

Jelte Jansen's avatar
Jelte Jansen committed
155
    // number overflows
Jelte Jansen's avatar
Jelte Jansen committed
156 157 158 159 160
    EXPECT_THROW(Element::fromJSON("12345678901234567890")->str(), JSONError);
    EXPECT_THROW(Element::fromJSON("1.1e12345678901234567890")->str(), JSONError);
    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 171 172 173
    double d;
    bool b;
    std::string s("asdf");
    std::vector<ElementPtr> v;
    std::map<std::string, ElementPtr> m;
    
174 175

    el = Element::create(1);
176
    EXPECT_NO_THROW(el->intValue());
177 178 179 180 181
    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
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
    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);
    ElementPtr tmp;
    EXPECT_FALSE(el->find("foo", tmp));
    
209 210

    el = Element::create(1.1);
211
    EXPECT_THROW(el->intValue(), TypeError);
212
    EXPECT_NO_THROW(el->doubleValue());
213 214 215 216
    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
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
    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));
232 233

    el = Element::create(true);
234 235
    EXPECT_THROW(el->intValue(), TypeError);
    EXPECT_THROW(el->doubleValue(), TypeError);
236
    EXPECT_NO_THROW(el->boolValue());
237 238 239
    EXPECT_THROW(el->stringValue(), TypeError);
    EXPECT_THROW(el->listValue(), TypeError);
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
240 241 242 243 244 245 246 247 248 249
    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));
    EXPECT_EQ(false, el->boolValue());
250 251

    el = Element::create("foo");
252 253 254
    EXPECT_THROW(el->intValue(), TypeError);
    EXPECT_THROW(el->doubleValue(), TypeError);
    EXPECT_THROW(el->boolValue(), TypeError);
255
    EXPECT_NO_THROW(el->stringValue());
256 257
    EXPECT_THROW(el->listValue(), TypeError);
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
258 259 260 261 262 263 264 265 266 267
    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());
268

269
    el = Element::createList();
270 271 272 273
    EXPECT_THROW(el->intValue(), TypeError);
    EXPECT_THROW(el->doubleValue(), TypeError);
    EXPECT_THROW(el->boolValue(), TypeError);
    EXPECT_THROW(el->stringValue(), TypeError);
274
    EXPECT_NO_THROW(el->listValue());
275
    EXPECT_THROW(el->mapValue(), TypeError);
Jelte Jansen's avatar
Jelte Jansen committed
276 277 278 279 280 281 282 283 284 285
    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());
286

287
    el = Element::createMap();
288 289 290 291 292
    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);
293
    EXPECT_NO_THROW(el->mapValue());
Jelte Jansen's avatar
Jelte Jansen committed
294 295 296 297 298 299
    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));
300 301 302 303 304

}

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

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

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

    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));
324
    EXPECT_EQ(el->get(2)->intValue(), 32);
325 326 327 328
}

TEST(Element, MapElement) {
    // this function checks the specific functions for ListElements
329
    ElementPtr el = Element::fromJSON("{ \"name\": \"foo\", \"value1\": \"bar\", \"value2\": { \"number\": 42 } }");
330 331
    ElementPtr el2;
    
332 333
    EXPECT_EQ(el->get("name")->stringValue(), "foo");
    EXPECT_EQ(el->get("value2")->getType(), Element::map);
334

335
    EXPECT_TRUE(isNull(el->get("value3")));
336 337

    el->set("value3", Element::create(47806));
338
    EXPECT_EQ(el->get("value3")->intValue(), 47806);
339 340

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

343
    EXPECT_EQ(el->find("value2/number")->intValue(), 42);
344
    EXPECT_TRUE(isNull(el->find("value2/nothing/")));
345
   
346 347
    EXPECT_EQ(el->find("value1")->stringValue(), "bar");
    EXPECT_EQ(el->find("value1/")->stringValue(), "bar");
348 349 350
    
    EXPECT_TRUE(el->find("value1", el2));
    EXPECT_FALSE(el->find("name/error", el2));
351 352 353 354 355 356 357 358

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

364 365
    el = Element::createMap();
    el->set(long_maptag, Element::create("bar"));
366 367
    EXPECT_EQ("bar", el->find(long_maptag)->stringValue());

368
    // A one-byte longer tag should still be allowed
369
    long_maptag.push_back('f');
370 371 372
    el = Element::fromJSON("{ \"" + long_maptag + "\": \"bar\"}");
    el->set(long_maptag, Element::create("bar"));
    EXPECT_EQ("bar", el->find(long_maptag)->stringValue());
373

374 375 376
}

TEST(Element, to_and_from_wire) {
377 378 379 380 381 382 383 384
    // Wire format is now plain JSON.
    ElementPtr el;
    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());
385 386
    EXPECT_EQ("[ \"a\", \"list\" ]", Element::fromJSON("[ \"a\", \"list\" ]")->toWire());
    EXPECT_EQ("{ \"a\": \"map\" }", Element::fromJSON("{ \"a\": \"map\" }")->toWire());
387 388

    EXPECT_EQ("1", Element::fromWire("1")->str());
Jelte Jansen's avatar
Jelte Jansen committed
389 390 391 392

    std::stringstream ss;
    ss << "1";
    EXPECT_EQ("1", Element::fromWire(ss, 1)->str());
393 394 395 396 397

    // Some malformed JSON input
    EXPECT_THROW(Element::fromJSON("{\":"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("]"), isc::data::JSONError);
    EXPECT_THROW(Element::fromJSON("[ 1, 2, }"), isc::data::JSONError);
398 399
}

400 401
static ElementPtr
efs(const std::string& str) {
402
    return Element::fromJSON(str);
403 404 405 406
}

TEST(Element, equals) {
    // why does EXPECT_EQ not work?
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 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
    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());
457 458 459
}

TEST(Element, removeIdentical) {
460 461 462
    ElementPtr a = Element::createMap();
    ElementPtr b = Element::createMap();
    ElementPtr c = Element::createMap();
463
    removeIdentical(a, b);
464
    EXPECT_EQ(a, c);
465

466 467
    a = Element::fromJSON("{ \"a\": 1 }");
    b = Element::fromJSON("{ \"a\": 1 }");
468
    c = Element::createMap();
469
    removeIdentical(a, b);
470
    EXPECT_EQ(a, c);
471

472
    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
473
    b = Element::createMap();
474
    c = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
475
    removeIdentical(a, b);
476
    EXPECT_EQ(a, c);
477

478 479
    a = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
    b = Element::fromJSON("{ \"a\": 1, \"b\": [ 1, 2 ] }");
480
    c = Element::createMap();
481
    removeIdentical(a, b);
482
    EXPECT_EQ(a, c);
483

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

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

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

502 503 504
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
505
    removeIdentical(a, b);
506
    EXPECT_EQ(a, c);
Jelte Jansen's avatar
Jelte Jansen committed
507 508

    EXPECT_THROW(removeIdentical(Element::create(1), Element::create(2)), TypeError);
509
}
510 511 512

TEST(Element, merge)
{
513 514 515
    ElementPtr a = Element::createMap();
    ElementPtr b = Element::createMap();
    ElementPtr c = Element::createMap();
516
    merge(a, b);
517
    EXPECT_EQ(a, c);
518

519
    a = Element::fromJSON("1");
520
    b = Element::createMap();
521 522
    EXPECT_THROW(merge(a, b), TypeError);

523
    a = Element::createMap();
524 525
    b = Element::fromJSON("{ \"a\": 1 }");
    c = Element::fromJSON("{ \"a\": 1 }");
526
    merge(a, b);
527 528 529 530 531 532 533
    EXPECT_EQ(a, c);

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

535 536 537
    a = Element::fromJSON("{ \"a\": 1 }");
    b = Element::fromJSON("{ \"a\": 2 }");
    c = Element::fromJSON("{ \"a\": 2 }");
538
    merge(a, b);
539 540 541 542 543 544 545
    EXPECT_EQ(a, c);

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

547 548 549
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"d\" } }");
550
    merge(a, b);
551 552 553 554 555 556 557
    EXPECT_EQ(a, c);

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

Jelte Jansen's avatar
Jelte Jansen committed
559 560 561 562
    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": null }");
    c = Element::fromJSON("{  }");
    merge(a, b);
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
    EXPECT_EQ(a, c);

    a = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    b = Element::fromJSON("{ \"a\": null }");
    c = Element::fromJSON("{ \"a\": { \"b\": \"c\" } }");
    merge(b, a);
    EXPECT_EQ(b, c);
    
    // 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);
    EXPECT_EQ(a, c);

    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);
    EXPECT_EQ(b, c);

    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);
    EXPECT_EQ(a, c);

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

596
}