/*** * ==++== * * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * ==--== * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * * construction_tests.cpp * * Tests creating JSON values. * * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ #include "stdafx.h" using namespace web; using namespace utility; namespace tests { namespace functional { namespace json_tests { SUITE(construction_tests) { #if defined(__cplusplus_winrt) TEST(winrt_platform_string) { Platform::String ^platformStr = "Hello!"; json::value jstr = json::value::string(platformStr->Data()); CHECK(jstr.is_string()); CHECK_EQUAL(jstr.serialize(), U("\"Hello!\"")); } #endif TEST(assignment_op) { json::value arr = json::value::array(); arr[0] = json::value(true); json::value ass_copy = arr; VERIFY_IS_TRUE(ass_copy.is_array()); VERIFY_ARE_EQUAL(U("true"), ass_copy[0].serialize()); ass_copy[1] = json::value(false); VERIFY_ARE_EQUAL(U("false"), ass_copy[1].serialize()); VERIFY_ARE_EQUAL(U("null"), arr[1].serialize()); } TEST(copy_ctor_array) { json::value arr = json::value::array(); arr[0] = json::value(true); json::value copy(arr); VERIFY_IS_TRUE(copy.is_array()); VERIFY_ARE_EQUAL(U("true"), copy[0].serialize()); copy[1] = json::value(false); VERIFY_ARE_EQUAL(U("false"), copy[1].serialize()); VERIFY_ARE_EQUAL(U("null"), arr[1].serialize()); } TEST(copy_ctor_object) { json::value obj = json::value::object(); utility::string_t keyName(U("key")); obj[keyName] = json::value(false); // Copy object that has values added. json::value copy(obj); VERIFY_IS_TRUE(copy.is_object()); VERIFY_ARE_EQUAL(U("false"), copy[keyName].serialize()); obj[keyName] = json::value(true); VERIFY_ARE_EQUAL(U("false"), copy[keyName].serialize()); VERIFY_ARE_EQUAL(U("true"), obj[keyName].serialize()); // Copy object that parses with value, but none additional added. obj = json::value::parse(U("{\"key\": true}")); json::value copy2(obj); VERIFY_IS_TRUE(copy2.is_object()); obj[keyName] = json::value(false); VERIFY_IS_TRUE(copy2.size() == 1); VERIFY_ARE_EQUAL(U("false"), obj[keyName].serialize()); VERIFY_ARE_EQUAL(U("true"), copy2[keyName].serialize()); } TEST(copy_ctor_string) { utility::string_t strValue(U("teststr")); json::value str = json::value::string(strValue); json::value copy(str); VERIFY_IS_TRUE(copy.is_string()); VERIFY_ARE_EQUAL(strValue, copy.as_string()); str = json::value::string(U("teststr2")); VERIFY_ARE_EQUAL(strValue, copy.as_string()); VERIFY_ARE_EQUAL(U("teststr2"), str.as_string()); } TEST(copy_ctor_with_escaped) { auto str = json::value::parse(U("\"\\n\"")); VERIFY_ARE_EQUAL(U("\n"), str.as_string()); auto copy = str; VERIFY_ARE_EQUAL(U("\n"), copy.as_string()); } TEST(move_ctor) { json::value obj; obj[U("A")] = json::value(true); json::value moved(std::move(obj)); VERIFY_IS_TRUE(moved.is_object()); VERIFY_ARE_EQUAL(U("true"), moved[U("A")].serialize()); moved[U("B")] = json::value(false); VERIFY_ARE_EQUAL(U("false"), moved[U("B")].serialize()); } TEST(move_assignment_op) { json::value obj; obj[U("A")] = json::value(true); json::value moved; moved = std::move(obj); VERIFY_IS_TRUE(moved.is_object()); VERIFY_ARE_EQUAL(U("true"), moved[U("A")].serialize()); moved[U("B")] = json::value(false); VERIFY_ARE_EQUAL(U("false"), moved[U("B")].serialize()); } TEST(constructor_overloads) { json::value v0; json::value v1(17); json::value v2(3.1415); json::value v3(true); const utility::char_t* p4 = U("Hello!"); json::value v4(p4); json::value v5(U("Hello Again!")); json::value v6(U("YES YOU KNOW IT")); json::value v7(U("HERE ID IS")); const utility::char_t* p9 = U("Hello not-escaped!"); json::value v8(p9, true); json::value v9(p9, false); VERIFY_ARE_EQUAL(v0.type(), json::value::Null); VERIFY_IS_TRUE(v0.is_null()); VERIFY_ARE_EQUAL(v1.type(), json::value::Number); VERIFY_IS_TRUE(v1.is_number()); VERIFY_IS_TRUE(v1.is_integer()); VERIFY_IS_FALSE(v1.is_double()); VERIFY_ARE_EQUAL(v2.type(), json::value::Number); VERIFY_IS_TRUE(v2.is_number()); VERIFY_IS_TRUE(v2.is_double()); VERIFY_IS_FALSE(v2.is_integer()); VERIFY_ARE_EQUAL(v3.type(), json::value::Boolean); VERIFY_IS_TRUE(v3.is_boolean()); VERIFY_ARE_EQUAL(v4.type(), json::value::String); VERIFY_IS_TRUE(v4.is_string()); VERIFY_ARE_EQUAL(v5.type(), json::value::String); VERIFY_IS_TRUE(v5.is_string()); VERIFY_ARE_EQUAL(v6.type(), json::value::String); VERIFY_IS_TRUE(v6.is_string()); VERIFY_ARE_EQUAL(v7.type(), json::value::String); VERIFY_IS_TRUE(v7.is_string()); VERIFY_ARE_EQUAL(v8.type(), json::value::String); VERIFY_IS_TRUE(v8.is_string()); VERIFY_ARE_EQUAL(v9.type(), json::value::String); VERIFY_IS_TRUE(v9.is_string()); } TEST(factory_overloads) { json::value v0 = json::value::null(); json::value v1 = json::value::number(17); json::value v2 = json::value::number(3.1415); json::value v3 = json::value::boolean(true); json::value v4 = json::value::string(U("Hello!")); json::value v5 = json::value::string(U("Hello Again!")); json::value v6 = json::value::string(U("Hello!")); json::value v7 = json::value::string(U("Hello Again!")); json::value v8 = json::value::string(U("Hello not-escaped!"), true); json::value v9 = json::value::string(U("Hello not-escaped!"), false); json::value v10 = json::value::object(); json::value v11 = json::value::array(); VERIFY_ARE_EQUAL(v0.type(), json::value::Null); VERIFY_ARE_EQUAL(v1.type(), json::value::Number); VERIFY_ARE_EQUAL(v2.type(), json::value::Number); VERIFY_ARE_EQUAL(v3.type(), json::value::Boolean); VERIFY_ARE_EQUAL(v4.type(), json::value::String); VERIFY_ARE_EQUAL(v5.type(), json::value::String); VERIFY_ARE_EQUAL(v6.type(), json::value::String); VERIFY_ARE_EQUAL(v7.type(), json::value::String); VERIFY_ARE_EQUAL(v8.type(), json::value::String); VERIFY_ARE_EQUAL(v9.type(), json::value::String); VERIFY_ARE_EQUAL(v10.type(), json::value::Object); VERIFY_IS_TRUE(v10.is_object()); VERIFY_ARE_EQUAL(v11.type(), json::value::Array); VERIFY_IS_TRUE(v11.is_array()); } TEST(object_construction) { // Factory which takes a vector. std::vector> f; f.push_back(std::make_pair(U("abc"), json::value(true))); f.push_back(std::make_pair(U("xyz"), json::value(44))); json::value obj = json::value::object(f); VERIFY_ARE_EQUAL(f.size(), obj.size()); obj[U("abc")] = json::value::string(U("str")); obj[U("123")] = json::value(false); VERIFY_ARE_NOT_EQUAL(f.size(), obj.size()); VERIFY_ARE_EQUAL(json::value::string(U("str")).serialize(), obj[U("abc")].serialize()); VERIFY_ARE_EQUAL(json::value(false).serialize(), obj[U("123")].serialize()); // Tests constructing empty and adding. auto val1 = json::value::object(); val1[U("A")] = 44; val1[U("hahah")] = json::value(true); VERIFY_ARE_EQUAL(2u, val1.size()); VERIFY_ARE_EQUAL(U("44"), val1[U("A")].serialize()); VERIFY_ARE_EQUAL(U("true"), val1[U("hahah")].serialize()); // Construct as null value, then turn into object. json::value val2; VERIFY_IS_TRUE(val2.is_null()); val2[U("A")] = 44; val2[U("hahah")] = json::value(true); VERIFY_ARE_EQUAL(2u, val2.size()); VERIFY_ARE_EQUAL(U("44"), val2[U("A")].serialize()); VERIFY_ARE_EQUAL(U("true"), val2[U("hahah")].serialize()); } TEST(object_construction_keep_order) { std::vector> f; f.push_back(std::make_pair(U("x"), json::value(0))); f.push_back(std::make_pair(U("a"), json::value(1))); auto obj1 = json::value::object(f, /*keep_order==*/ true); VERIFY_ARE_EQUAL(obj1.as_object().begin()->first, U("x")); auto obj2 = json::value::object(f, /*keep_order==*/ false); VERIFY_ARE_EQUAL(obj2.as_object().begin()->first, U("a")); } TEST(object_construction_from_null_keep_order) { struct restore { ~restore() { json::keep_object_element_order(false); } }_; json::keep_object_element_order(true); auto val1 = json::value::null(); val1[U("B")] = 1; val1[U("A")] = 1; VERIFY_ARE_EQUAL(val1.as_object().begin()->first, U("B")); json::keep_object_element_order(false); auto val2 = json::value::null(); val2[U("B")] = 1; val2[U("A")] = 1; VERIFY_ARE_EQUAL(val2.as_object().begin()->first, U("A")); } TEST(array_construction) { // Constructor which takes a vector. std::vector e; e.push_back(json::value(false)); e.push_back(json::value::string(U("hehe"))); json::value arr = json::value::array(e); VERIFY_ARE_EQUAL(e.size(), arr.size()); VERIFY_ARE_EQUAL(U("false"), arr[0].serialize()); arr[3] = json::value(22); VERIFY_ARE_NOT_EQUAL(e.size(), arr.size()); VERIFY_ARE_EQUAL(U("22"), arr[3].serialize()); // Test empty factory and adding. auto arr2 = json::value::array(); arr2[1] = json::value(false); arr2[0] = json::value::object(); arr2[0][U("A")] = json::value::string(U("HE")); VERIFY_ARE_EQUAL(2u, arr2.size()); VERIFY_ARE_EQUAL(U("false"), arr2[1].serialize()); VERIFY_ARE_EQUAL(U("\"HE\""), arr2[0][U("A")].serialize()); // Construct as null value and then add elements. json::value arr3; VERIFY_IS_TRUE(arr3.is_null()); arr3[1] = json::value(false); // Element [0] should already behave as an object. arr3[0][U("A")] = json::value::string(U("HE")); VERIFY_ARE_EQUAL(2u, arr3.size()); VERIFY_ARE_EQUAL(U("false"), arr3[1].serialize()); VERIFY_ARE_EQUAL(U("\"HE\""), arr3[0][U("A")].serialize()); // Test factory which takes a size. auto arr4 = json::value::array(2); VERIFY_IS_TRUE(arr4[0].is_null()); VERIFY_IS_TRUE(arr4[1].is_null()); arr4[2] = json::value(true); arr4[0] = json::value(false); VERIFY_ARE_EQUAL(U("false"), arr4[0].serialize()); VERIFY_ARE_EQUAL(U("true"), arr4[2].serialize()); } TEST(array_test) { json::value arr = json::value::array(); const json::value& carr = arr; arr[0] = json::value(3.14); arr[1] = json::value(true); arr[2] = json::value("Yes"); int count; json::array& array = arr.as_array(); const json::array& carray = arr.as_array(); VERIFY_THROWS(array.at(4), json::json_exception); VERIFY_THROWS(carray.at(5), json::json_exception); VERIFY_THROWS(arr.at(6), json::json_exception); VERIFY_THROWS(carr.at(7), json::json_exception); // The begin and end iterators on non-const instances count = 0; for(auto iter = array.begin(); iter != array.end(); ++iter) { VERIFY_IS_TRUE((*iter) == array[count]); VERIFY_IS_TRUE((*iter) == array.at(count)); VERIFY_IS_TRUE((*iter) == carray.at(count)); count++; } VERIFY_ARE_EQUAL(array.size(), count); count = 0; for(auto iter = array.cbegin(); iter != array.cend(); ++iter) { VERIFY_IS_TRUE((*iter) == array[count]); VERIFY_IS_TRUE((*iter) == array.at(count)); count++; } VERIFY_ARE_EQUAL(array.size(), count); count = 0; for(auto iter = array.rbegin(); iter != array.rend(); ++iter) { VERIFY_IS_TRUE((*iter) == array[array.size()-1-count]); VERIFY_IS_TRUE((*iter) == array.at(array.size()-1-count)); VERIFY_IS_TRUE((*iter) == carray.at(array.size()-1-count)); count++; } VERIFY_ARE_EQUAL(array.size(), count); count = 0; for(auto iter = array.crbegin(); iter != array.crend(); ++iter) { VERIFY_IS_TRUE((*iter) == array[array.size()-1-count]); VERIFY_IS_TRUE((*iter) == arr[array.size()-1-count]); VERIFY_IS_TRUE((*iter) == array.at(array.size()-1-count)); VERIFY_IS_TRUE((*iter) == arr.at(array.size()-1-count)); count++; } VERIFY_ARE_EQUAL(array.size(), count); // The begin and end iterators on const instances count = 0; for(auto iter = carray.begin(); iter != carray.end(); ++iter) { VERIFY_IS_TRUE((*iter) == carray.at(count)); VERIFY_IS_TRUE((*iter) == carr.at(count)); count++; } VERIFY_ARE_EQUAL(array.size(), count); count = 0; for(auto iter = carray.rbegin(); iter != carray.rend(); ++iter) { VERIFY_IS_TRUE((*iter) == carray.at(array.size()-1-count)); VERIFY_IS_TRUE((*iter) == carr.at(array.size()-1-count)); count++; } VERIFY_ARE_EQUAL(array.size(), count); } TEST(object_test) { json::value obj = json::value::object(); const json::value& cobj = obj; json::object& object = obj.as_object(); const json::object& cobject = obj.as_object(); VERIFY_IS_TRUE(object.empty()); obj[U("name")] = json::value(U("John")); obj[U("surname")] = json::value(U("Smith")); obj[U("height")] = json::value(5.9); obj[U("vegetarian")] = json::value(true); int count; //Test at() VERIFY_ARE_EQUAL(U("John"), obj.at(U("name")).as_string()); VERIFY_ARE_EQUAL(U("John"), cobj.at(U("name")).as_string()); VERIFY_ARE_EQUAL(U("Smith"), object.at(U("surname")).as_string()); VERIFY_ARE_EQUAL(U("Smith"), cobject.at(U("surname")).as_string()); VERIFY_THROWS(obj.at(U("wrong key")), json::json_exception); VERIFY_THROWS(cobj.at(U("wrong key")), json::json_exception); //Test find() { auto iter = object.find(U("height")); VERIFY_ARE_NOT_EQUAL(object.end(), iter); VERIFY_IS_TRUE(iter->second.is_number()); VERIFY_ARE_EQUAL(5.9, iter->second.as_number().to_double()); VERIFY_ARE_EQUAL(object.end(), object.find(U("wrong_key"))); } //Test find() const auto citer = cobject.find(U("height")); VERIFY_ARE_NOT_EQUAL(cobject.end(), citer); VERIFY_IS_TRUE(citer->second.is_number()); VERIFY_ARE_EQUAL(5.9, citer->second.as_number().to_double()); VERIFY_ARE_EQUAL(cobject.end(), cobject.find(U("wrong_key"))); VERIFY_IS_FALSE(object.empty()); // The begin and end iterators on non-const instances count = 0; for(auto iter = object.begin(); iter != object.end(); ++iter) { VERIFY_ARE_EQUAL(object[iter->first], iter->second); count++; } VERIFY_ARE_EQUAL(object.size(), count); count = 0; for(auto iter = object.rbegin(); iter != object.rend(); ++iter) { VERIFY_ARE_EQUAL(object[iter->first], iter->second); count++; } VERIFY_ARE_EQUAL(object.size(), count); count = 0; for(auto iter = object.cbegin(); iter != object.cend(); ++iter) { VERIFY_ARE_EQUAL(object[iter->first], iter->second); count++; } VERIFY_ARE_EQUAL(object.size(), count); count = 0; for(auto iter = object.crbegin(); iter != object.crend(); ++iter) { VERIFY_ARE_EQUAL(object[iter->first], iter->second); count++; } VERIFY_ARE_EQUAL(object.size(), count); // The begin and end iterators on const instances count = 0; for(auto iter = cobject.begin(); iter != cobject.end(); ++iter) { VERIFY_ARE_EQUAL(cobject.find(iter->first)->second, iter->second); count++; } VERIFY_ARE_EQUAL(cobject.size(), count); count = 0; for(auto iter = cobject.rbegin(); iter != cobject.rend(); ++iter) { VERIFY_ARE_EQUAL(cobject.find(iter->first)->second, iter->second); count++; } VERIFY_ARE_EQUAL(cobject.size(), count); } } // SUITE(construction_tests) }}}