mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
Prepare wpiutil for merge into allwpilib.
This commit is contained in:
310
wpiutil/src/test/native/cpp/json/unit-algorithms.cpp
Normal file
310
wpiutil/src/test/native/cpp/json/unit-algorithms.cpp
Normal file
@@ -0,0 +1,310 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
class JsonAlgorithmsTest : public ::testing::Test {
|
||||
protected:
|
||||
json j_array = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz"};
|
||||
json j_object = {{"one", 1}, {"two", 2}};
|
||||
};
|
||||
|
||||
// non-modifying sequence operations
|
||||
TEST_F(JsonAlgorithmsTest, AllOf)
|
||||
{
|
||||
EXPECT_TRUE(std::all_of(j_array.begin(), j_array.end(), [](const json & value)
|
||||
{
|
||||
return value.size() > 0;
|
||||
}));
|
||||
EXPECT_TRUE(std::all_of(j_object.begin(), j_object.end(), [](const json & value)
|
||||
{
|
||||
return value.type() == json::value_t::number_integer;
|
||||
}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, AnyOf)
|
||||
{
|
||||
EXPECT_TRUE(std::any_of(j_array.begin(), j_array.end(), [](const json & value)
|
||||
{
|
||||
return value.is_string() && value.get<std::string>() == "foo";
|
||||
}));
|
||||
EXPECT_TRUE(std::any_of(j_object.begin(), j_object.end(), [](const json & value)
|
||||
{
|
||||
return value.get<int>() > 1;
|
||||
}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, NoneOf)
|
||||
{
|
||||
EXPECT_TRUE(std::none_of(j_array.begin(), j_array.end(), [](const json & value)
|
||||
{
|
||||
return value.size() == 0;
|
||||
}));
|
||||
EXPECT_TRUE(std::none_of(j_object.begin(), j_object.end(), [](const json & value)
|
||||
{
|
||||
return value.get<int>() <= 0;
|
||||
}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, ForEachReading)
|
||||
{
|
||||
int sum = 0;
|
||||
|
||||
std::for_each(j_array.cbegin(), j_array.cend(), [&sum](const json & value)
|
||||
{
|
||||
if (value.is_number())
|
||||
{
|
||||
sum += static_cast<int>(value);
|
||||
}
|
||||
});
|
||||
|
||||
EXPECT_EQ(sum, 45);
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, ForEachWriting)
|
||||
{
|
||||
auto add17 = [](json & value)
|
||||
{
|
||||
if (value.is_array())
|
||||
{
|
||||
value.push_back(17);
|
||||
}
|
||||
};
|
||||
|
||||
std::for_each(j_array.begin(), j_array.end(), add17);
|
||||
|
||||
EXPECT_EQ(j_array[6], json({1, 2, 3, 17}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, Count)
|
||||
{
|
||||
EXPECT_EQ(std::count(j_array.begin(), j_array.end(), json(true)), 1);
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, CountIf)
|
||||
{
|
||||
auto count1 = std::count_if(j_array.begin(), j_array.end(), [](const json & value)
|
||||
{
|
||||
return (value.is_number());
|
||||
});
|
||||
EXPECT_EQ(count1, 3);
|
||||
auto count2 = std::count_if(j_array.begin(), j_array.end(), [](const json&)
|
||||
{
|
||||
return true;
|
||||
});
|
||||
EXPECT_EQ(count2, 9);
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, Mismatch)
|
||||
{
|
||||
json j_array2 = {13, 29, 3, {{"one", 1}, {"two", 2}, {"three", 3}}, true, false, {1, 2, 3}, "foo", "baz"};
|
||||
auto res = std::mismatch(j_array.begin(), j_array.end(), j_array2.begin());
|
||||
EXPECT_EQ(*res.first, json({{"one", 1}, {"two", 2}}));
|
||||
EXPECT_EQ(*res.second, json({{"one", 1}, {"two", 2}, {"three", 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, EqualOperatorEquals)
|
||||
{
|
||||
EXPECT_TRUE(std::equal(j_array.begin(), j_array.end(), j_array.begin()));
|
||||
EXPECT_TRUE(std::equal(j_object.begin(), j_object.end(), j_object.begin()));
|
||||
EXPECT_FALSE(std::equal(j_array.begin(), j_array.end(), j_object.begin()));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, EqualUserComparison)
|
||||
{
|
||||
// compare objects only by size of its elements
|
||||
json j_array2 = {13, 29, 3, {"Hello", "World"}, true, false, {{"one", 1}, {"two", 2}, {"three", 3}}, "foo", "baz"};
|
||||
EXPECT_FALSE(std::equal(j_array.begin(), j_array.end(), j_array2.begin()));
|
||||
EXPECT_TRUE(std::equal(j_array.begin(), j_array.end(), j_array2.begin(),
|
||||
[](const json & a, const json & b)
|
||||
{
|
||||
return (a.size() == b.size());
|
||||
}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, Find)
|
||||
{
|
||||
auto it = std::find(j_array.begin(), j_array.end(), json(false));
|
||||
EXPECT_EQ(std::distance(j_array.begin(), it), 5);
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, FindIf)
|
||||
{
|
||||
auto it = std::find_if(j_array.begin(), j_array.end(),
|
||||
[](const json & value)
|
||||
{
|
||||
return value.is_boolean();
|
||||
});
|
||||
EXPECT_EQ(std::distance(j_array.begin(), it), 4);
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, FindIfNot)
|
||||
{
|
||||
auto it = std::find_if_not(j_array.begin(), j_array.end(),
|
||||
[](const json & value)
|
||||
{
|
||||
return value.is_number();
|
||||
});
|
||||
EXPECT_EQ(std::distance(j_array.begin(), it), 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, AdjacentFind)
|
||||
{
|
||||
EXPECT_EQ(std::adjacent_find(j_array.begin(), j_array.end()), j_array.end());
|
||||
auto it = std::adjacent_find(j_array.begin(), j_array.end(),
|
||||
[](const json & v1, const json & v2)
|
||||
{
|
||||
return v1.type() == v2.type();
|
||||
});
|
||||
EXPECT_EQ(it, j_array.begin());
|
||||
}
|
||||
|
||||
// modifying sequence operations
|
||||
TEST_F(JsonAlgorithmsTest, Reverse)
|
||||
{
|
||||
std::reverse(j_array.begin(), j_array.end());
|
||||
EXPECT_EQ(j_array, json({"baz", "foo", {1, 2, 3}, false, true, {{"one", 1}, {"two", 2}}, 3, 29, 13}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, Rotate)
|
||||
{
|
||||
std::rotate(j_array.begin(), j_array.begin() + 1, j_array.end());
|
||||
EXPECT_EQ(j_array, json({29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", 13}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, Partition)
|
||||
{
|
||||
auto it = std::partition(j_array.begin(), j_array.end(), [](const json & v)
|
||||
{
|
||||
return v.is_string();
|
||||
});
|
||||
EXPECT_EQ(std::distance(j_array.begin(), it), 2);
|
||||
EXPECT_FALSE(it[2].is_string());
|
||||
}
|
||||
|
||||
// sorting operations
|
||||
TEST_F(JsonAlgorithmsTest, SortOperatorEquals)
|
||||
{
|
||||
json j = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", nullptr};
|
||||
std::sort(j.begin(), j.end());
|
||||
EXPECT_EQ(j, json({nullptr, false, true, 3, 13, 29, {{"one", 1}, {"two", 2}}, {1, 2, 3}, "baz", "foo"}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, SortUserComparison)
|
||||
{
|
||||
json j = {3, {{"one", 1}, {"two", 2}}, {1, 2, 3}, nullptr};
|
||||
std::sort(j.begin(), j.end(), [](const json & a, const json & b)
|
||||
{
|
||||
return a.size() < b.size();
|
||||
});
|
||||
EXPECT_EQ(j, json({nullptr, 3, {{"one", 1}, {"two", 2}}, {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, SortObject)
|
||||
{
|
||||
json j({{"one", 1}, {"two", 2}});
|
||||
EXPECT_THROW_MSG(std::sort(j.begin(), j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, PartialSort)
|
||||
{
|
||||
json j = {13, 29, 3, {{"one", 1}, {"two", 2}}, true, false, {1, 2, 3}, "foo", "baz", nullptr};
|
||||
std::partial_sort(j.begin(), j.begin() + 4, j.end());
|
||||
EXPECT_EQ(j, json({nullptr, false, true, 3, {{"one", 1}, {"two", 2}}, 29, {1, 2, 3}, "foo", "baz", 13}));
|
||||
}
|
||||
|
||||
// set operations
|
||||
TEST_F(JsonAlgorithmsTest, Merge)
|
||||
{
|
||||
json j1 = {2, 4, 6, 8};
|
||||
json j2 = {1, 2, 3, 5, 7};
|
||||
json j3;
|
||||
|
||||
std::merge(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
|
||||
EXPECT_EQ(j3, json({1, 2, 2, 3, 4, 5, 6, 7, 8}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, SetDifference)
|
||||
{
|
||||
json j1 = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
json j2 = {1, 2, 3, 5, 7};
|
||||
json j3;
|
||||
|
||||
std::set_difference(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
|
||||
EXPECT_EQ(j3, json({4, 6, 8}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, SetIntersection)
|
||||
{
|
||||
json j1 = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
json j2 = {1, 2, 3, 5, 7};
|
||||
json j3;
|
||||
|
||||
std::set_intersection(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
|
||||
EXPECT_EQ(j3, json({1, 2, 3, 5, 7}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, SetUnion)
|
||||
{
|
||||
json j1 = {2, 4, 6, 8};
|
||||
json j2 = {1, 2, 3, 5, 7};
|
||||
json j3;
|
||||
|
||||
std::set_union(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
|
||||
EXPECT_EQ(j3, json({1, 2, 3, 4, 5, 6, 7, 8}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, SetSymmetricDifference)
|
||||
{
|
||||
json j1 = {2, 4, 6, 8};
|
||||
json j2 = {1, 2, 3, 5, 7};
|
||||
json j3;
|
||||
|
||||
std::set_symmetric_difference(j1.begin(), j1.end(), j2.begin(), j2.end(), std::back_inserter(j3));
|
||||
EXPECT_EQ(j3, json({1, 3, 4, 5, 6, 7, 8}));
|
||||
}
|
||||
|
||||
TEST_F(JsonAlgorithmsTest, HeapOperations)
|
||||
{
|
||||
std::make_heap(j_array.begin(), j_array.end());
|
||||
EXPECT_TRUE(std::is_heap(j_array.begin(), j_array.end()));
|
||||
std::sort_heap(j_array.begin(), j_array.end());
|
||||
EXPECT_EQ(j_array, json({false, true, 3, 13, 29, {{"one", 1}, {"two", 2}}, {1, 2, 3}, "baz", "foo"}));
|
||||
}
|
||||
528
wpiutil/src/test/native/cpp/json/unit-capacity.cpp
Normal file
528
wpiutil/src/test/native/cpp/json/unit-capacity.cpp
Normal file
@@ -0,0 +1,528 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
TEST(JsonEmptyTest, Boolean)
|
||||
{
|
||||
json j = true;
|
||||
json j_const(j);
|
||||
|
||||
// result of empty
|
||||
{
|
||||
EXPECT_FALSE(j.empty());
|
||||
EXPECT_FALSE(j_const.empty());
|
||||
}
|
||||
|
||||
// definition of empty
|
||||
{
|
||||
EXPECT_EQ(j.empty(), (j.begin() == j.end()));
|
||||
EXPECT_EQ(j_const.empty(), (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonEmptyTest, String)
|
||||
{
|
||||
json j = "hello world";
|
||||
json j_const(j);
|
||||
|
||||
// result of empty
|
||||
{
|
||||
EXPECT_FALSE(j.empty());
|
||||
EXPECT_FALSE(j_const.empty());
|
||||
}
|
||||
|
||||
// definition of empty
|
||||
{
|
||||
EXPECT_EQ(j.empty(), (j.begin() == j.end()));
|
||||
EXPECT_EQ(j_const.empty(), (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonEmptyTest, ArrayEmpty)
|
||||
{
|
||||
json j = json::array();
|
||||
json j_const(j);
|
||||
|
||||
// result of empty
|
||||
{
|
||||
EXPECT_TRUE(j.empty());
|
||||
EXPECT_TRUE(j_const.empty());
|
||||
}
|
||||
|
||||
// definition of empty
|
||||
{
|
||||
EXPECT_EQ(j.empty(), (j.begin() == j.end()));
|
||||
EXPECT_EQ(j_const.empty(), (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonEmptyTest, ArrayFilled)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
json j_const(j);
|
||||
|
||||
// result of empty
|
||||
{
|
||||
EXPECT_FALSE(j.empty());
|
||||
EXPECT_FALSE(j_const.empty());
|
||||
}
|
||||
|
||||
// definition of empty
|
||||
{
|
||||
EXPECT_EQ(j.empty(), (j.begin() == j.end()));
|
||||
EXPECT_EQ(j_const.empty(), (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonEmptyTest, ObjectEmpty)
|
||||
{
|
||||
json j = json::object();
|
||||
json j_const(j);
|
||||
|
||||
// result of empty
|
||||
{
|
||||
EXPECT_TRUE(j.empty());
|
||||
EXPECT_TRUE(j_const.empty());
|
||||
}
|
||||
|
||||
// definition of empty
|
||||
{
|
||||
EXPECT_EQ(j.empty(), (j.begin() == j.end()));
|
||||
EXPECT_EQ(j_const.empty(), (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonEmptyTest, ObjectFilled)
|
||||
{
|
||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
json j_const(j);
|
||||
|
||||
// result of empty
|
||||
{
|
||||
EXPECT_FALSE(j.empty());
|
||||
EXPECT_FALSE(j_const.empty());
|
||||
}
|
||||
|
||||
// definition of empty
|
||||
{
|
||||
EXPECT_EQ(j.empty(), (j.begin() == j.end()));
|
||||
EXPECT_EQ(j_const.empty(), (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonEmptyTest, NumberInteger)
|
||||
{
|
||||
json j = 23;
|
||||
json j_const(j);
|
||||
|
||||
// result of empty
|
||||
{
|
||||
EXPECT_FALSE(j.empty());
|
||||
EXPECT_FALSE(j_const.empty());
|
||||
}
|
||||
|
||||
// definition of empty
|
||||
{
|
||||
EXPECT_EQ(j.empty(), (j.begin() == j.end()));
|
||||
EXPECT_EQ(j_const.empty(), (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonEmptyTest, NumberUnsigned)
|
||||
{
|
||||
json j = 23u;
|
||||
json j_const(j);
|
||||
|
||||
// result of empty
|
||||
{
|
||||
EXPECT_FALSE(j.empty());
|
||||
EXPECT_FALSE(j_const.empty());
|
||||
}
|
||||
|
||||
// definition of empty
|
||||
{
|
||||
EXPECT_EQ(j.empty(), (j.begin() == j.end()));
|
||||
EXPECT_EQ(j_const.empty(), (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonEmptyTest, NumberFloat)
|
||||
{
|
||||
json j = 23.42;
|
||||
json j_const(j);
|
||||
|
||||
// result of empty
|
||||
{
|
||||
EXPECT_FALSE(j.empty());
|
||||
EXPECT_FALSE(j_const.empty());
|
||||
}
|
||||
|
||||
// definition of empty
|
||||
{
|
||||
EXPECT_EQ(j.empty(), (j.begin() == j.end()));
|
||||
EXPECT_EQ(j_const.empty(), (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonEmptyTest, Null)
|
||||
{
|
||||
json j = nullptr;
|
||||
json j_const(j);
|
||||
|
||||
// result of empty
|
||||
{
|
||||
EXPECT_TRUE(j.empty());
|
||||
EXPECT_TRUE(j_const.empty());
|
||||
}
|
||||
|
||||
// definition of empty
|
||||
{
|
||||
EXPECT_EQ(j.empty(), (j.begin() == j.end()));
|
||||
EXPECT_EQ(j_const.empty(), (j_const.begin() == j_const.end()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonSizeTest, Boolean)
|
||||
{
|
||||
json j = true;
|
||||
json j_const(j);
|
||||
|
||||
// result of size
|
||||
{
|
||||
EXPECT_EQ(j.size(), 1u);
|
||||
EXPECT_EQ(j_const.size(), 1u);
|
||||
}
|
||||
|
||||
// definition of size
|
||||
{
|
||||
EXPECT_EQ(std::distance(j.begin(), j.end()), static_cast<int>(j.size()));
|
||||
EXPECT_EQ(std::distance(j_const.begin(), j_const.end()),
|
||||
static_cast<int>(j_const.size()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonSizeTest, String)
|
||||
{
|
||||
json j = "hello world";
|
||||
json j_const(j);
|
||||
|
||||
// result of size
|
||||
{
|
||||
EXPECT_EQ(j.size(), 1u);
|
||||
EXPECT_EQ(j_const.size(), 1u);
|
||||
}
|
||||
|
||||
// definition of size
|
||||
{
|
||||
EXPECT_EQ(std::distance(j.begin(), j.end()), static_cast<int>(j.size()));
|
||||
EXPECT_EQ(std::distance(j_const.begin(), j_const.end()),
|
||||
static_cast<int>(j_const.size()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonSizeTest, ArrayEmpty)
|
||||
{
|
||||
json j = json::array();
|
||||
json j_const(j);
|
||||
|
||||
// result of size
|
||||
{
|
||||
EXPECT_EQ(j.size(), 0u);
|
||||
EXPECT_EQ(j_const.size(), 0u);
|
||||
}
|
||||
|
||||
// definition of size
|
||||
{
|
||||
EXPECT_EQ(std::distance(j.begin(), j.end()), static_cast<int>(j.size()));
|
||||
EXPECT_EQ(std::distance(j_const.begin(), j_const.end()),
|
||||
static_cast<int>(j_const.size()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonSizeTest, ArrayFilled)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
json j_const(j);
|
||||
|
||||
// result of size
|
||||
{
|
||||
EXPECT_EQ(j.size(), 3u);
|
||||
EXPECT_EQ(j_const.size(), 3u);
|
||||
}
|
||||
|
||||
// definition of size
|
||||
{
|
||||
EXPECT_EQ(std::distance(j.begin(), j.end()), static_cast<int>(j.size()));
|
||||
EXPECT_EQ(std::distance(j_const.begin(), j_const.end()),
|
||||
static_cast<int>(j_const.size()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonSizeTest, ObjectEmpty)
|
||||
{
|
||||
json j = json::object();
|
||||
json j_const(j);
|
||||
|
||||
// result of size
|
||||
{
|
||||
EXPECT_EQ(j.size(), 0u);
|
||||
EXPECT_EQ(j_const.size(), 0u);
|
||||
}
|
||||
|
||||
// definition of size
|
||||
{
|
||||
EXPECT_EQ(std::distance(j.begin(), j.end()), static_cast<int>(j.size()));
|
||||
EXPECT_EQ(std::distance(j_const.begin(), j_const.end()),
|
||||
static_cast<int>(j_const.size()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonSizeTest, ObjectFilled)
|
||||
{
|
||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
json j_const(j);
|
||||
|
||||
// result of size
|
||||
{
|
||||
EXPECT_EQ(j.size(), 3u);
|
||||
EXPECT_EQ(j_const.size(), 3u);
|
||||
}
|
||||
|
||||
// definition of size
|
||||
{
|
||||
EXPECT_EQ(std::distance(j.begin(), j.end()), static_cast<int>(j.size()));
|
||||
EXPECT_EQ(std::distance(j_const.begin(), j_const.end()),
|
||||
static_cast<int>(j_const.size()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonSizeTest, NumberInteger)
|
||||
{
|
||||
json j = 23;
|
||||
json j_const(j);
|
||||
|
||||
// result of size
|
||||
{
|
||||
EXPECT_EQ(j.size(), 1u);
|
||||
EXPECT_EQ(j_const.size(), 1u);
|
||||
}
|
||||
|
||||
// definition of size
|
||||
{
|
||||
EXPECT_EQ(std::distance(j.begin(), j.end()), static_cast<int>(j.size()));
|
||||
EXPECT_EQ(std::distance(j_const.begin(), j_const.end()),
|
||||
static_cast<int>(j_const.size()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonSizeTest, NumberUnsigned)
|
||||
{
|
||||
json j = 23u;
|
||||
json j_const(j);
|
||||
|
||||
// result of size
|
||||
{
|
||||
EXPECT_EQ(j.size(), 1u);
|
||||
EXPECT_EQ(j_const.size(), 1u);
|
||||
}
|
||||
|
||||
// definition of size
|
||||
{
|
||||
EXPECT_EQ(std::distance(j.begin(), j.end()), static_cast<int>(j.size()));
|
||||
EXPECT_EQ(std::distance(j_const.begin(), j_const.end()),
|
||||
static_cast<int>(j_const.size()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonSizeTest, NumberFloat)
|
||||
{
|
||||
json j = 23.42;
|
||||
json j_const(j);
|
||||
|
||||
// result of size
|
||||
{
|
||||
EXPECT_EQ(j.size(), 1u);
|
||||
EXPECT_EQ(j_const.size(), 1u);
|
||||
}
|
||||
|
||||
// definition of size
|
||||
{
|
||||
EXPECT_EQ(std::distance(j.begin(), j.end()), static_cast<int>(j.size()));
|
||||
EXPECT_EQ(std::distance(j_const.begin(), j_const.end()),
|
||||
static_cast<int>(j_const.size()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonSizeTest, Null)
|
||||
{
|
||||
json j = nullptr;
|
||||
json j_const(j);
|
||||
|
||||
// result of size
|
||||
{
|
||||
EXPECT_EQ(j.size(), 0u);
|
||||
EXPECT_EQ(j_const.size(), 0u);
|
||||
}
|
||||
|
||||
// definition of size
|
||||
{
|
||||
EXPECT_EQ(std::distance(j.begin(), j.end()), static_cast<int>(j.size()));
|
||||
EXPECT_EQ(std::distance(j_const.begin(), j_const.end()),
|
||||
static_cast<int>(j_const.size()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonMaxSizeTest, Boolean)
|
||||
{
|
||||
json j = true;
|
||||
json j_const(j);
|
||||
|
||||
// result of max_size
|
||||
{
|
||||
EXPECT_EQ(j.max_size(), 1u);
|
||||
EXPECT_EQ(j_const.max_size(), 1u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonMaxSizeTest, String)
|
||||
{
|
||||
json j = "hello world";
|
||||
json j_const(j);
|
||||
|
||||
// result of max_size
|
||||
{
|
||||
EXPECT_EQ(j.max_size(), 1u);
|
||||
EXPECT_EQ(j_const.max_size(), 1u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonMaxSizeTest, ArrayEmpty)
|
||||
{
|
||||
json j = json::array();
|
||||
json j_const(j);
|
||||
|
||||
// result of max_size
|
||||
{
|
||||
EXPECT_GE(j.max_size(), j.size());
|
||||
EXPECT_GE(j_const.max_size(), j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonMaxSizeTest, ArrayFilled)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
json j_const(j);
|
||||
|
||||
// result of max_size
|
||||
{
|
||||
EXPECT_GE(j.max_size(), j.size());
|
||||
EXPECT_GE(j_const.max_size(), j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonMaxSizeTest, ObjectEmpty)
|
||||
{
|
||||
json j = json::object();
|
||||
json j_const(j);
|
||||
|
||||
// result of max_size
|
||||
{
|
||||
EXPECT_GE(j.max_size(), j.size());
|
||||
EXPECT_GE(j_const.max_size(), j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonMaxSizeTest, ObjectFilled)
|
||||
{
|
||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
json j_const(j);
|
||||
|
||||
// result of max_size
|
||||
{
|
||||
EXPECT_GE(j.max_size(), j.size());
|
||||
EXPECT_GE(j_const.max_size(), j_const.size());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonMaxSizeTest, NumberInteger)
|
||||
{
|
||||
json j = 23;
|
||||
json j_const(j);
|
||||
|
||||
// result of max_size
|
||||
{
|
||||
EXPECT_EQ(j.max_size(), 1u);
|
||||
EXPECT_EQ(j_const.max_size(), 1u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonMaxSizeTest, NumberUnsigned)
|
||||
{
|
||||
json j = 23u;
|
||||
json j_const(j);
|
||||
|
||||
// result of max_size
|
||||
{
|
||||
EXPECT_EQ(j.max_size(), 1u);
|
||||
EXPECT_EQ(j_const.max_size(), 1u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonMaxSizeTest, NumberFloat)
|
||||
{
|
||||
json j = 23.42;
|
||||
json j_const(j);
|
||||
|
||||
// result of max_size
|
||||
{
|
||||
EXPECT_EQ(j.max_size(), 1u);
|
||||
EXPECT_EQ(j_const.max_size(), 1u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonMaxSizeTest, Null)
|
||||
{
|
||||
json j = nullptr;
|
||||
json j_const(j);
|
||||
|
||||
// result of max_size
|
||||
{
|
||||
EXPECT_EQ(j.max_size(), 0u);
|
||||
EXPECT_EQ(j_const.max_size(), 0u);
|
||||
}
|
||||
}
|
||||
1689
wpiutil/src/test/native/cpp/json/unit-cbor.cpp
Normal file
1689
wpiutil/src/test/native/cpp/json/unit-cbor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
250
wpiutil/src/test/native/cpp/json/unit-comparison.cpp
Normal file
250
wpiutil/src/test/native/cpp/json/unit-comparison.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
class JsonComparisonTypesTest : public ::testing::Test {
|
||||
protected:
|
||||
std::vector<json::value_t> j_types =
|
||||
{
|
||||
json::value_t::null,
|
||||
json::value_t::boolean,
|
||||
json::value_t::number_integer,
|
||||
json::value_t::number_unsigned,
|
||||
json::value_t::number_float,
|
||||
json::value_t::object,
|
||||
json::value_t::array,
|
||||
json::value_t::string
|
||||
};
|
||||
};
|
||||
|
||||
TEST_F(JsonComparisonTypesTest, Less)
|
||||
{
|
||||
static const std::vector<std::vector<bool>> expected =
|
||||
{
|
||||
{false, true, true, true, true, true, true, true},
|
||||
{false, false, true, true, true, true, true, true},
|
||||
{false, false, false, false, false, true, true, true},
|
||||
{false, false, false, false, false, true, true, true},
|
||||
{false, false, false, false, false, true, true, true},
|
||||
{false, false, false, false, false, false, true, true},
|
||||
{false, false, false, false, false, false, false, true},
|
||||
{false, false, false, false, false, false, false, false}
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < j_types.size(); ++i)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
for (size_t j = 0; j < j_types.size(); ++j)
|
||||
{
|
||||
SCOPED_TRACE(j);
|
||||
// check precomputed values
|
||||
EXPECT_EQ(operator<(j_types[i], j_types[j]), expected[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JsonComparisonValuesTest : public ::testing::Test {
|
||||
protected:
|
||||
json j_values =
|
||||
{
|
||||
nullptr, nullptr,
|
||||
17, 42,
|
||||
8u, 13u,
|
||||
3.14159, 23.42,
|
||||
"foo", "bar",
|
||||
true, false,
|
||||
{1, 2, 3}, {"one", "two", "three"},
|
||||
{{"first", 1}, {"second", 2}}, {{"a", "A"}, {"b", {"B"}}}
|
||||
};
|
||||
};
|
||||
|
||||
TEST_F(JsonComparisonValuesTest, Equal)
|
||||
{
|
||||
static const std::vector<std::vector<bool>> expected =
|
||||
{
|
||||
{true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{true, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true}
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
SCOPED_TRACE(j);
|
||||
// check precomputed values
|
||||
EXPECT_EQ(j_values[i] == j_values[j], expected[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// comparison with discarded elements
|
||||
json j_discarded(json::value_t::discarded);
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
EXPECT_FALSE(j_values[i] == j_discarded);
|
||||
EXPECT_FALSE(j_discarded == j_values[i]);
|
||||
EXPECT_FALSE(j_discarded == j_discarded);
|
||||
}
|
||||
|
||||
// compare with null pointer
|
||||
json j_null;
|
||||
EXPECT_TRUE(j_null == nullptr);
|
||||
EXPECT_TRUE(nullptr == j_null);
|
||||
}
|
||||
|
||||
TEST_F(JsonComparisonValuesTest, NotEqual)
|
||||
{
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
SCOPED_TRACE(j);
|
||||
// check definition
|
||||
EXPECT_EQ(j_values[i] != j_values[j], !(j_values[i] == j_values[j]));
|
||||
}
|
||||
}
|
||||
|
||||
// compare with null pointer
|
||||
json j_null;
|
||||
EXPECT_FALSE(j_null != nullptr);
|
||||
EXPECT_FALSE(nullptr != j_null);
|
||||
EXPECT_EQ(j_null != nullptr, !(j_null == nullptr));
|
||||
EXPECT_EQ(nullptr != j_null, !(nullptr == j_null));
|
||||
}
|
||||
|
||||
TEST_F(JsonComparisonValuesTest, Less)
|
||||
{
|
||||
static const std::vector<std::vector<bool>> expected =
|
||||
{
|
||||
{false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true},
|
||||
{false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true},
|
||||
{false, false, false, true, false, false, false, true, true, true, false, false, true, true, true, true},
|
||||
{false, false, false, false, false, false, false, false, true, true, false, false, true, true, true, true},
|
||||
{false, false, true, true, false, true, false, true, true, true, false, false, true, true, true, true},
|
||||
{false, false, true, true, false, false, false, true, true, true, false, false, true, true, true, true},
|
||||
{false, false, true, true, true, true, false, true, true, true, false, false, true, true, true, true},
|
||||
{false, false, false, true, false, false, false, false, true, true, false, false, true, true, true, true},
|
||||
{false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false},
|
||||
{false, false, true, true, true, true, true, true, true, true, false, false, true, true, true, true},
|
||||
{false, false, true, true, true, true, true, true, true, true, true, false, true, true, true, true},
|
||||
{false, false, false, false, false, false, false, false, true, true, false, false, false, true, false, false},
|
||||
{false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false},
|
||||
{false, false, false, false, false, false, false, false, true, true, false, false, true, true, false, false},
|
||||
{false, false, false, false, false, false, false, false, true, true, false, false, true, true, true, false}
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
SCOPED_TRACE(j);
|
||||
// check precomputed values
|
||||
EXPECT_EQ(j_values[i] < j_values[j], expected[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// comparison with discarded elements
|
||||
json j_discarded(json::value_t::discarded);
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
EXPECT_FALSE(j_values[i] < j_discarded);
|
||||
EXPECT_FALSE(j_discarded < j_values[i]);
|
||||
EXPECT_FALSE(j_discarded < j_discarded);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(JsonComparisonValuesTest, LessEqual)
|
||||
{
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
SCOPED_TRACE(j);
|
||||
// check definition
|
||||
EXPECT_EQ(j_values[i] <= j_values[j], !(j_values[j] < j_values[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(JsonComparisonValuesTest, Greater)
|
||||
{
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
SCOPED_TRACE(j);
|
||||
// check definition
|
||||
EXPECT_EQ(j_values[i] > j_values[j], j_values[j] < j_values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(JsonComparisonValuesTest, GreaterEqual)
|
||||
{
|
||||
for (size_t i = 0; i < j_values.size(); ++i)
|
||||
{
|
||||
SCOPED_TRACE(i);
|
||||
for (size_t j = 0; j < j_values.size(); ++j)
|
||||
{
|
||||
SCOPED_TRACE(j);
|
||||
// check definition
|
||||
EXPECT_EQ(j_values[i] >= j_values[j], !(j_values[i] < j_values[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
166
wpiutil/src/test/native/cpp/json/unit-concepts.cpp
Normal file
166
wpiutil/src/test/native/cpp/json/unit-concepts.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
TEST(JsonConceptsTest, ContainerRequirements)
|
||||
{
|
||||
// X: container class: json
|
||||
// T: type of objects: json
|
||||
// a, b: values of type X: json
|
||||
|
||||
// TABLE 96 - Container Requirements
|
||||
|
||||
// X::value_type must return T
|
||||
EXPECT_TRUE((std::is_same<json::value_type, json>::value));
|
||||
|
||||
// X::reference must return lvalue of T
|
||||
EXPECT_TRUE((std::is_same<json::reference, json&>::value));
|
||||
|
||||
// X::const_reference must return const lvalue of T
|
||||
EXPECT_TRUE((std::is_same<json::const_reference, const json&>::value));
|
||||
|
||||
// X::iterator must return iterator whose value_type is T
|
||||
EXPECT_TRUE((std::is_same<json::iterator::value_type, json>::value));
|
||||
// X::iterator must meet the forward iterator requirements
|
||||
EXPECT_TRUE((std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<json::iterator>::iterator_category>::value));
|
||||
// X::iterator must be convertible to X::const_iterator
|
||||
EXPECT_TRUE((std::is_convertible<json::iterator, json::const_iterator>::value));
|
||||
|
||||
// X::const_iterator must return iterator whose value_type is T
|
||||
EXPECT_TRUE((std::is_same<json::const_iterator::value_type, json>::value));
|
||||
// X::const_iterator must meet the forward iterator requirements
|
||||
EXPECT_TRUE((std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<json::const_iterator>::iterator_category>::value));
|
||||
|
||||
// X::difference_type must return a signed integer
|
||||
EXPECT_TRUE((std::is_signed<json::difference_type>::value));
|
||||
// X::difference_type must be identical to X::iterator::difference_type
|
||||
EXPECT_TRUE((std::is_same<json::difference_type, json::iterator::difference_type>::value));
|
||||
// X::difference_type must be identical to X::const_iterator::difference_type
|
||||
EXPECT_TRUE((std::is_same<json::difference_type, json::const_iterator::difference_type>::value));
|
||||
|
||||
// X::size_type must return an unsigned integer
|
||||
EXPECT_TRUE((std::is_unsigned<json::size_type>::value));
|
||||
// X::size_type can represent any non-negative value of X::difference_type
|
||||
EXPECT_TRUE(static_cast<json::size_type>(std::numeric_limits<json::difference_type>::max()) <=
|
||||
std::numeric_limits<json::size_type>::max());
|
||||
|
||||
// the expression "X u" has the post-condition "u.empty()"
|
||||
{
|
||||
json u;
|
||||
EXPECT_TRUE(u.empty());
|
||||
}
|
||||
|
||||
// the expression "X()" has the post-condition "X().empty()"
|
||||
EXPECT_TRUE(json().empty());
|
||||
}
|
||||
|
||||
TEST(JsonConceptsTest, DefaultConstructible)
|
||||
{
|
||||
EXPECT_TRUE(std::is_nothrow_default_constructible<json>::value);
|
||||
}
|
||||
|
||||
TEST(JsonConceptsTest, MoveConstructible)
|
||||
{
|
||||
EXPECT_TRUE(std::is_nothrow_move_constructible<json>::value);
|
||||
}
|
||||
|
||||
TEST(JsonConceptsTest, CopyConstructible)
|
||||
{
|
||||
EXPECT_TRUE(std::is_copy_constructible<json>::value);
|
||||
}
|
||||
|
||||
TEST(JsonConceptsTest, MoveAssignable)
|
||||
{
|
||||
EXPECT_TRUE(std::is_nothrow_move_assignable<json>::value);
|
||||
}
|
||||
|
||||
TEST(JsonConceptsTest, CopyAssignable)
|
||||
{
|
||||
EXPECT_TRUE(std::is_copy_assignable<json>::value);
|
||||
}
|
||||
|
||||
TEST(JsonConceptsTest, Destructible)
|
||||
{
|
||||
EXPECT_TRUE(std::is_nothrow_destructible<json>::value);
|
||||
}
|
||||
|
||||
TEST(JsonConceptsTest, StandardLayoutType)
|
||||
{
|
||||
EXPECT_TRUE(std::is_standard_layout<json>::value);
|
||||
}
|
||||
|
||||
TEST(JsonIteratorConceptsTest, CopyConstructible)
|
||||
{
|
||||
EXPECT_TRUE(std::is_nothrow_copy_constructible<json::iterator>::value);
|
||||
EXPECT_TRUE(std::is_nothrow_copy_constructible<json::const_iterator>::value);
|
||||
}
|
||||
|
||||
TEST(JsonIteratorConceptsTest, CopyAssignable)
|
||||
{
|
||||
// STL iterators used by json::iterator don't pass this test in Debug mode
|
||||
#if !defined(_MSC_VER) || (_ITERATOR_DEBUG_LEVEL == 0)
|
||||
EXPECT_TRUE(std::is_nothrow_copy_assignable<json::iterator>::value);
|
||||
EXPECT_TRUE(std::is_nothrow_copy_assignable<json::const_iterator>::value);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(JsonIteratorConceptsTest, Destructible)
|
||||
{
|
||||
EXPECT_TRUE(std::is_nothrow_destructible<json::iterator>::value);
|
||||
EXPECT_TRUE(std::is_nothrow_destructible<json::const_iterator>::value);
|
||||
}
|
||||
|
||||
TEST(JsonIteratorConceptsTest, Swappable)
|
||||
{
|
||||
json j {1, 2, 3};
|
||||
json::iterator it1 = j.begin();
|
||||
json::iterator it2 = j.end();
|
||||
std::swap(it1, it2);
|
||||
EXPECT_EQ(it1, j.end());
|
||||
EXPECT_EQ(it2, j.begin());
|
||||
}
|
||||
|
||||
TEST(JsonIteratorConceptsTest, SwappableConst)
|
||||
{
|
||||
json j {1, 2, 3};
|
||||
json::const_iterator it1 = j.cbegin();
|
||||
json::const_iterator it2 = j.cend();
|
||||
std::swap(it1, it2);
|
||||
EXPECT_EQ(it1, j.end());
|
||||
EXPECT_EQ(it2, j.begin());
|
||||
}
|
||||
1071
wpiutil/src/test/native/cpp/json/unit-constructor1.cpp
Normal file
1071
wpiutil/src/test/native/cpp/json/unit-constructor1.cpp
Normal file
File diff suppressed because it is too large
Load Diff
185
wpiutil/src/test/native/cpp/json/unit-constructor2.cpp
Normal file
185
wpiutil/src/test/native/cpp/json/unit-constructor2.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
TEST(JsonCopyConstructorTest, Object)
|
||||
{
|
||||
json j {{"foo", 1}, {"bar", false}};
|
||||
json k(j);
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyConstructorTest, Array)
|
||||
{
|
||||
json j {"foo", 1, 42.23, false};
|
||||
json k(j);
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyConstructorTest, Null)
|
||||
{
|
||||
json j(nullptr);
|
||||
json k(j);
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyConstructorTest, Boolean)
|
||||
{
|
||||
json j(true);
|
||||
json k(j);
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyConstructorTest, String)
|
||||
{
|
||||
json j("Hello world");
|
||||
json k(j);
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyConstructorTest, Integer)
|
||||
{
|
||||
json j(42);
|
||||
json k(j);
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyConstructorTest, Unsigned)
|
||||
{
|
||||
json j(42u);
|
||||
json k(j);
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyConstructorTest, Float)
|
||||
{
|
||||
json j(42.23);
|
||||
json k(j);
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonMoveConstructorTest, Case)
|
||||
{
|
||||
json j {{"foo", "bar"}, {"baz", {1, 2, 3, 4}}, {"a", 42u}, {"b", 42.23}, {"c", nullptr}};
|
||||
EXPECT_EQ(j.type(), json::value_t::object);
|
||||
json k(std::move(j));
|
||||
EXPECT_EQ(k.type(), json::value_t::object);
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonCopyAssignmentTest, Object)
|
||||
{
|
||||
json j {{"foo", 1}, {"bar", false}};
|
||||
json k;
|
||||
k = j;
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyAssignmentTest, Array)
|
||||
{
|
||||
json j {"foo", 1, 42.23, false};
|
||||
json k;
|
||||
k = j;
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyAssignmentTest, Null)
|
||||
{
|
||||
json j(nullptr);
|
||||
json k;
|
||||
k = j;
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyAssignmentTest, Boolean)
|
||||
{
|
||||
json j(true);
|
||||
json k;
|
||||
k = j;
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyAssignmentTest, String)
|
||||
{
|
||||
json j("Hello world");
|
||||
json k;
|
||||
k = j;
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyAssignmentTest, Integer)
|
||||
{
|
||||
json j(42);
|
||||
json k;
|
||||
k = j;
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyAssignmentTest, Unsigned)
|
||||
{
|
||||
json j(42u);
|
||||
json k;
|
||||
k = j;
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonCopyAssignmentTest, Float)
|
||||
{
|
||||
json j(42.23);
|
||||
json k;
|
||||
k = j;
|
||||
EXPECT_EQ(j, k);
|
||||
}
|
||||
|
||||
TEST(JsonDestructorTest, Object)
|
||||
{
|
||||
auto j = new json {{"foo", 1}, {"bar", false}};
|
||||
delete j;
|
||||
}
|
||||
|
||||
TEST(JsonDestructorTest, Array)
|
||||
{
|
||||
auto j = new json {"foo", 1, 1u, false, 23.42};
|
||||
delete j;
|
||||
}
|
||||
|
||||
TEST(JsonDestructorTest, String)
|
||||
{
|
||||
auto j = new json("Hello world");
|
||||
delete j;
|
||||
}
|
||||
121
wpiutil/src/test/native/cpp/json/unit-convenience.cpp
Normal file
121
wpiutil/src/test/native/cpp/json/unit-convenience.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "llvm/SmallString.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
|
||||
#include "support/json_serializer.h"
|
||||
|
||||
using wpi::json;
|
||||
|
||||
class JsonTypeNameTest
|
||||
: public ::testing::TestWithParam<std::pair<json::value_t, const char*>> {};
|
||||
TEST_P(JsonTypeNameTest, Case)
|
||||
{
|
||||
EXPECT_EQ(json(GetParam().first).type_name(), GetParam().second);
|
||||
}
|
||||
|
||||
static const std::pair<json::value_t, const char*> type_name_cases[] = {
|
||||
{json::value_t::null, "null"},
|
||||
{json::value_t::object, "object"},
|
||||
{json::value_t::array, "array"},
|
||||
{json::value_t::number_integer, "number"},
|
||||
{json::value_t::number_unsigned, "number"},
|
||||
{json::value_t::number_float, "number"},
|
||||
{json::value_t::boolean, "boolean"},
|
||||
{json::value_t::string, "string"},
|
||||
{json::value_t::discarded, "discarded"},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(JsonTypeNameTests, JsonTypeNameTest,
|
||||
::testing::ValuesIn(type_name_cases), );
|
||||
|
||||
class JsonStringEscapeTest
|
||||
: public ::testing::TestWithParam<std::pair<const char*, const char*>> {};
|
||||
TEST_P(JsonStringEscapeTest, Case)
|
||||
{
|
||||
llvm::SmallString<32> buf;
|
||||
llvm::raw_svector_ostream ss(buf);
|
||||
json::serializer s(ss);
|
||||
s.dump_escaped(GetParam().first);
|
||||
EXPECT_EQ(ss.str(), llvm::StringRef(GetParam().second));
|
||||
}
|
||||
|
||||
static const std::pair<const char*, const char*> string_escape_cases[] = {
|
||||
{"\"", "\\\""},
|
||||
{"\\", "\\\\"},
|
||||
{"\b", "\\b"},
|
||||
{"\f", "\\f"},
|
||||
{"\n", "\\n"},
|
||||
{"\r", "\\r"},
|
||||
{"\t", "\\t"},
|
||||
|
||||
{"\x01", "\\u0001"},
|
||||
{"\x02", "\\u0002"},
|
||||
{"\x03", "\\u0003"},
|
||||
{"\x04", "\\u0004"},
|
||||
{"\x05", "\\u0005"},
|
||||
{"\x06", "\\u0006"},
|
||||
{"\x07", "\\u0007"},
|
||||
{"\x08", "\\b"},
|
||||
{"\x09", "\\t"},
|
||||
{"\x0a", "\\n"},
|
||||
{"\x0b", "\\u000b"},
|
||||
{"\x0c", "\\f"},
|
||||
{"\x0d", "\\r"},
|
||||
{"\x0e", "\\u000e"},
|
||||
{"\x0f", "\\u000f"},
|
||||
{"\x10", "\\u0010"},
|
||||
{"\x11", "\\u0011"},
|
||||
{"\x12", "\\u0012"},
|
||||
{"\x13", "\\u0013"},
|
||||
{"\x14", "\\u0014"},
|
||||
{"\x15", "\\u0015"},
|
||||
{"\x16", "\\u0016"},
|
||||
{"\x17", "\\u0017"},
|
||||
{"\x18", "\\u0018"},
|
||||
{"\x19", "\\u0019"},
|
||||
{"\x1a", "\\u001a"},
|
||||
{"\x1b", "\\u001b"},
|
||||
{"\x1c", "\\u001c"},
|
||||
{"\x1d", "\\u001d"},
|
||||
{"\x1e", "\\u001e"},
|
||||
{"\x1f", "\\u001f"},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(JsonStringEscapeTests, JsonStringEscapeTest,
|
||||
::testing::ValuesIn(string_escape_cases), );
|
||||
560
wpiutil/src/test/native/cpp/json/unit-conversions.cpp
Normal file
560
wpiutil/src/test/native/cpp/json/unit-conversions.cpp
Normal file
@@ -0,0 +1,560 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
using wpi::JsonTest;
|
||||
|
||||
#include <deque>
|
||||
//#include <forward_list>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
template <typename T>
|
||||
class JsonGetObjectTest : public ::testing::Test {
|
||||
public:
|
||||
JsonGetObjectTest() : j(o_reference) {}
|
||||
|
||||
protected:
|
||||
json::object_t o_reference = {{"object", json::object()}, {"array", {1, 2, 3, 4}}, {"number", 42}, {"boolean", false}, {"null", nullptr}, {"string", "Hello world"} };
|
||||
json j;
|
||||
};
|
||||
|
||||
typedef ::testing::Types<
|
||||
json::object_t
|
||||
, std::map<json::string_t, json>
|
||||
, std::multimap<json::string_t, json>
|
||||
, std::unordered_map<json::string_t, json>
|
||||
, std::unordered_multimap<json::string_t, json>
|
||||
> JsonGetObjectTestTypes;
|
||||
TYPED_TEST_CASE(JsonGetObjectTest, JsonGetObjectTestTypes);
|
||||
|
||||
TYPED_TEST(JsonGetObjectTest, Explicit)
|
||||
{
|
||||
TypeParam o = (this->j).template get<TypeParam>();
|
||||
EXPECT_EQ(json(o), this->j);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonGetObjectTest, Implicit)
|
||||
{
|
||||
TypeParam o = this->j;
|
||||
EXPECT_EQ(json(o), this->j);
|
||||
}
|
||||
|
||||
// exception in case of a non-object type
|
||||
TEST(JsonGetObjectExceptionTest, TypeError)
|
||||
{
|
||||
EXPECT_THROW_MSG(json(json::value_t::null).get<json::object_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be object, but is null");
|
||||
EXPECT_THROW_MSG(json(json::value_t::array).get<json::object_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be object, but is array");
|
||||
EXPECT_THROW_MSG(json(json::value_t::string).get<json::object_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be object, but is string");
|
||||
EXPECT_THROW_MSG(json(json::value_t::boolean).get<json::object_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be object, but is boolean");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_integer).get<json::object_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be object, but is number");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_unsigned).get<json::object_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be object, but is number");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_float).get<json::object_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be object, but is number");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class JsonGetArrayTest : public ::testing::Test {
|
||||
public:
|
||||
JsonGetArrayTest() : j(a_reference) {}
|
||||
|
||||
protected:
|
||||
json::array_t a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()};
|
||||
json j;
|
||||
};
|
||||
|
||||
typedef ::testing::Types<json::array_t, std::list<json>,
|
||||
/*std::forward_list<json>,*/ std::vector<json>,
|
||||
std::deque<json>>
|
||||
JsonGetArrayTestTypes;
|
||||
TYPED_TEST_CASE(JsonGetArrayTest, JsonGetArrayTestTypes);
|
||||
|
||||
TYPED_TEST(JsonGetArrayTest, Explicit)
|
||||
{
|
||||
TypeParam a = (this->j).template get<TypeParam>();
|
||||
EXPECT_EQ(json(a), this->j);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonGetArrayTest, Implicit)
|
||||
{
|
||||
TypeParam a = this->j;
|
||||
EXPECT_EQ(json(a), this->j);
|
||||
}
|
||||
|
||||
#if !defined(JSON_NOEXCEPTION)
|
||||
// reserve is called on containers that supports it
|
||||
TEST(JsonGetArrayAdditionalTest, ExplicitStdVectorReserve)
|
||||
{
|
||||
json::array_t a_reference {json(1), json(1u), json(2.2), json(false), json("string"), json()};
|
||||
json j(a_reference);
|
||||
|
||||
// making the call to from_json throw in order to check capacity
|
||||
std::vector<float> v;
|
||||
EXPECT_THROW(wpi::from_json(j, v), json::type_error);
|
||||
EXPECT_EQ(v.capacity(), j.size());
|
||||
|
||||
// make sure all values are properly copied
|
||||
std::vector<int> v2 = json({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
|
||||
EXPECT_EQ(v2.size(), 10u);
|
||||
}
|
||||
#endif
|
||||
|
||||
// built-in arrays
|
||||
TEST(JsonGetArrayAdditionalTest, ExplicitBuiltinArray)
|
||||
{
|
||||
const char str[] = "a string";
|
||||
const int nbs[] = {0, 1, 2};
|
||||
|
||||
json j2 = nbs;
|
||||
json j3 = str;
|
||||
|
||||
auto v = j2.get<std::vector<int>>();
|
||||
auto s = j3.get<std::string>();
|
||||
EXPECT_TRUE(std::equal(v.begin(), v.end(), std::begin(nbs)));
|
||||
EXPECT_EQ(s, str);
|
||||
}
|
||||
#if 0
|
||||
TEST(JsonGetArrayExceptionTest, ForwardList)
|
||||
{
|
||||
EXPECT_THROW_MSG(json(json::value_t::null).get<std::forward_list<json>>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
}
|
||||
#endif
|
||||
TEST(JsonGetArrayExceptionTest, StdVector)
|
||||
{
|
||||
EXPECT_THROW_MSG(json(json::value_t::null).get<std::vector<json>>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
}
|
||||
|
||||
// exception in case of a non-array type
|
||||
TEST(JsonGetArrayExceptionTest, TypeError)
|
||||
{
|
||||
EXPECT_THROW_MSG(json(json::value_t::object).get<std::vector<int>>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is object");
|
||||
EXPECT_THROW_MSG(json(json::value_t::null).get<json::array_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
EXPECT_THROW_MSG(json(json::value_t::object).get<json::array_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is object");
|
||||
EXPECT_THROW_MSG(json(json::value_t::string).get<json::array_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is string");
|
||||
EXPECT_THROW_MSG(json(json::value_t::boolean).get<json::array_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is boolean");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_integer).get<json::array_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is number");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_unsigned).get<json::array_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is number");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_float).get<json::array_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is number");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class JsonGetStringTest : public ::testing::Test {
|
||||
public:
|
||||
JsonGetStringTest() : j(s_reference) {}
|
||||
|
||||
protected:
|
||||
json::string_t s_reference {"Hello world"};
|
||||
json j;
|
||||
};
|
||||
|
||||
typedef ::testing::Types<json::string_t, std::string> JsonGetStringTestTypes;
|
||||
TYPED_TEST_CASE(JsonGetStringTest, JsonGetStringTestTypes);
|
||||
|
||||
TYPED_TEST(JsonGetStringTest, Explicit)
|
||||
{
|
||||
TypeParam s = (this->j).template get<TypeParam>();
|
||||
EXPECT_EQ(json(s), this->j);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonGetStringTest, Implicit)
|
||||
{
|
||||
TypeParam s = this->j;
|
||||
EXPECT_EQ(json(s), this->j);
|
||||
}
|
||||
|
||||
// exception in case of a non-string type
|
||||
TEST(JsonGetStringExceptionTest, TypeError)
|
||||
{
|
||||
EXPECT_THROW_MSG(json(json::value_t::null).get<json::string_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be string, but is null");
|
||||
EXPECT_THROW_MSG(json(json::value_t::object).get<json::string_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be string, but is object");
|
||||
EXPECT_THROW_MSG(json(json::value_t::array).get<json::string_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be string, but is array");
|
||||
EXPECT_THROW_MSG(json(json::value_t::boolean).get<json::string_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be string, but is boolean");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_integer).get<json::string_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be string, but is number");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_unsigned).get<json::string_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be string, but is number");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_float).get<json::string_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be string, but is number");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class JsonGetBooleanTest : public ::testing::Test {
|
||||
public:
|
||||
JsonGetBooleanTest() : j(b_reference) {}
|
||||
|
||||
protected:
|
||||
json::boolean_t b_reference {true};
|
||||
json j;
|
||||
};
|
||||
|
||||
typedef ::testing::Types<json::boolean_t, bool> JsonGetBooleanTestTypes;
|
||||
TYPED_TEST_CASE(JsonGetBooleanTest, JsonGetBooleanTestTypes);
|
||||
|
||||
TYPED_TEST(JsonGetBooleanTest, Explicit)
|
||||
{
|
||||
TypeParam b = (this->j).template get<TypeParam>();
|
||||
EXPECT_EQ(json(b), this->j);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonGetBooleanTest, Implicit)
|
||||
{
|
||||
TypeParam b = this->j;
|
||||
EXPECT_EQ(json(b), this->j);
|
||||
}
|
||||
|
||||
// exception in case of a non-string type
|
||||
TEST(JsonGetBooleanExceptionTest, TypeError)
|
||||
{
|
||||
EXPECT_THROW_MSG(json(json::value_t::null).get<json::boolean_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be boolean, but is null");
|
||||
EXPECT_THROW_MSG(json(json::value_t::object).get<json::boolean_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be boolean, but is object");
|
||||
EXPECT_THROW_MSG(json(json::value_t::array).get<json::boolean_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be boolean, but is array");
|
||||
EXPECT_THROW_MSG(json(json::value_t::string).get<json::boolean_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be boolean, but is string");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_integer).get<json::boolean_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be boolean, but is number");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_unsigned).get<json::boolean_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be boolean, but is number");
|
||||
EXPECT_THROW_MSG(json(json::value_t::number_float).get<json::boolean_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be boolean, but is number");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class JsonGetIntegerTest : public ::testing::Test {
|
||||
public:
|
||||
JsonGetIntegerTest() : j(n_reference), j_unsigned(n_unsigned_reference) {}
|
||||
|
||||
protected:
|
||||
json::number_integer_t n_reference {42};
|
||||
json j;
|
||||
json::number_unsigned_t n_unsigned_reference {42u};
|
||||
json j_unsigned;
|
||||
};
|
||||
|
||||
typedef ::testing::Types<
|
||||
short
|
||||
, unsigned short
|
||||
, int
|
||||
, unsigned int
|
||||
, long
|
||||
, unsigned long
|
||||
, long long
|
||||
, unsigned long long
|
||||
, int8_t
|
||||
, int16_t
|
||||
, int32_t
|
||||
, int64_t
|
||||
#if 0
|
||||
, int8_fast_t
|
||||
, int16_fast_t
|
||||
, int32_fast_t
|
||||
, int64_fast_t
|
||||
, int8_least_t
|
||||
, int16_least_t
|
||||
, int32_least_t
|
||||
, int64_least_t
|
||||
#endif
|
||||
, uint8_t
|
||||
, uint16_t
|
||||
, uint32_t
|
||||
, uint64_t
|
||||
#if 0
|
||||
, uint8_fast_t
|
||||
, uint16_fast_t
|
||||
, uint32_fast_t
|
||||
, uint64_fast_t
|
||||
, uint8_least_t
|
||||
, uint16_least_t
|
||||
, uint32_least_t
|
||||
, uint64_least_t
|
||||
#endif
|
||||
> JsonGetIntegerTestTypes;
|
||||
|
||||
TYPED_TEST_CASE(JsonGetIntegerTest, JsonGetIntegerTestTypes);
|
||||
|
||||
TYPED_TEST(JsonGetIntegerTest, Explicit)
|
||||
{
|
||||
TypeParam n = (this->j).template get<TypeParam>();
|
||||
EXPECT_EQ(json(n), this->j);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonGetIntegerTest, Implicit)
|
||||
{
|
||||
if (std::is_unsigned<TypeParam>::value)
|
||||
{
|
||||
TypeParam n = this->j_unsigned;
|
||||
EXPECT_EQ(json(n), this->j_unsigned);
|
||||
}
|
||||
else
|
||||
{
|
||||
TypeParam n = this->j;
|
||||
EXPECT_EQ(json(n), this->j);
|
||||
}
|
||||
}
|
||||
|
||||
// exception in case of a non-number type
|
||||
TEST(JsonGetIntegerExceptionTest, TypeError)
|
||||
{
|
||||
EXPECT_THROW_MSG(json(json::value_t::null).get<json::number_integer_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be number, but is null");
|
||||
EXPECT_THROW_MSG(json(json::value_t::object).get<json::number_integer_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be number, but is object");
|
||||
EXPECT_THROW_MSG(json(json::value_t::array).get<json::number_integer_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be number, but is array");
|
||||
EXPECT_THROW_MSG(json(json::value_t::string).get<json::number_integer_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be number, but is string");
|
||||
EXPECT_THROW_MSG(json(json::value_t::boolean).get<json::number_integer_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be number, but is boolean");
|
||||
|
||||
EXPECT_NO_THROW(json(json::value_t::number_float).get<json::number_integer_t>());
|
||||
EXPECT_NO_THROW(json(json::value_t::number_float).get<json::number_unsigned_t>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class JsonGetFloatTest : public ::testing::Test {
|
||||
public:
|
||||
JsonGetFloatTest() : j(n_reference) {}
|
||||
|
||||
protected:
|
||||
json::number_float_t n_reference {42.23};
|
||||
json j;
|
||||
};
|
||||
|
||||
typedef ::testing::Types<json::number_float_t, float, double>
|
||||
JsonGetFloatTestTypes;
|
||||
|
||||
TYPED_TEST_CASE(JsonGetFloatTest, JsonGetFloatTestTypes);
|
||||
|
||||
TYPED_TEST(JsonGetFloatTest, Explicit)
|
||||
{
|
||||
TypeParam n = (this->j).template get<TypeParam>();
|
||||
EXPECT_LT(std::fabs(JsonTest::GetValue(json(n)).number_float -
|
||||
JsonTest::GetValue(this->j).number_float), 0.001);
|
||||
}
|
||||
|
||||
TYPED_TEST(JsonGetFloatTest, Implicit)
|
||||
{
|
||||
TypeParam n = this->j;
|
||||
EXPECT_LT(std::fabs(JsonTest::GetValue(json(n)).number_float -
|
||||
JsonTest::GetValue(this->j).number_float), 0.001);
|
||||
}
|
||||
|
||||
// exception in case of a non-string type
|
||||
TEST(JsonGetFloatExceptionTest, TypeError)
|
||||
{
|
||||
EXPECT_THROW_MSG(json(json::value_t::null).get<json::number_float_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be number, but is null");
|
||||
EXPECT_THROW_MSG(json(json::value_t::object).get<json::number_float_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be number, but is object");
|
||||
EXPECT_THROW_MSG(json(json::value_t::array).get<json::number_float_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be number, but is array");
|
||||
EXPECT_THROW_MSG(json(json::value_t::string).get<json::number_float_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be number, but is string");
|
||||
EXPECT_THROW_MSG(json(json::value_t::boolean).get<json::number_float_t>(), json::type_error,
|
||||
"[json.exception.type_error.302] type must be number, but is boolean");
|
||||
|
||||
EXPECT_NO_THROW(json(json::value_t::number_integer).get<json::number_float_t>());
|
||||
EXPECT_NO_THROW(json(json::value_t::number_unsigned).get<json::number_float_t>());
|
||||
}
|
||||
|
||||
TEST(JsonGetEnumTest, Case)
|
||||
{
|
||||
enum c_enum { value_1, value_2 };
|
||||
enum class cpp_enum { value_1, value_2 };
|
||||
|
||||
EXPECT_EQ(json(value_1).get<c_enum>(), value_1);
|
||||
EXPECT_EQ(json(cpp_enum::value_1).get<cpp_enum>(), cpp_enum::value_1);
|
||||
}
|
||||
|
||||
class JsonObjectConversionTest : public ::testing::Test {
|
||||
protected:
|
||||
json j1 = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
json j2 = {{"one", 1u}, {"two", 2u}, {"three", 3u}};
|
||||
json j3 = {{"one", 1.1}, {"two", 2.2}, {"three", 3.3}};
|
||||
json j4 = {{"one", true}, {"two", false}, {"three", true}};
|
||||
json j5 = {{"one", "eins"}, {"two", "zwei"}, {"three", "drei"}};
|
||||
};
|
||||
|
||||
TEST_F(JsonObjectConversionTest, StdMap)
|
||||
{
|
||||
auto m1 = j1.get<std::map<std::string, int>>();
|
||||
auto m2 = j2.get<std::map<std::string, unsigned int>>();
|
||||
auto m3 = j3.get<std::map<std::string, double>>();
|
||||
auto m4 = j4.get<std::map<std::string, bool>>();
|
||||
//auto m5 = j5.get<std::map<std::string, std::string>>();
|
||||
}
|
||||
|
||||
TEST_F(JsonObjectConversionTest, StdUnorderedMap)
|
||||
{
|
||||
auto m1 = j1.get<std::unordered_map<std::string, int>>();
|
||||
auto m2 = j2.get<std::unordered_map<std::string, unsigned int>>();
|
||||
auto m3 = j3.get<std::unordered_map<std::string, double>>();
|
||||
auto m4 = j4.get<std::unordered_map<std::string, bool>>();
|
||||
//auto m5 = j5.get<std::unordered_map<std::string, std::string>>();
|
||||
//CHECK(m5["one"] == "eins");
|
||||
}
|
||||
|
||||
TEST_F(JsonObjectConversionTest, StdMultiMap)
|
||||
{
|
||||
auto m1 = j1.get<std::multimap<std::string, int>>();
|
||||
auto m2 = j2.get<std::multimap<std::string, unsigned int>>();
|
||||
auto m3 = j3.get<std::multimap<std::string, double>>();
|
||||
auto m4 = j4.get<std::multimap<std::string, bool>>();
|
||||
//auto m5 = j5.get<std::multimap<std::string, std::string>>();
|
||||
//CHECK(m5["one"] == "eins");
|
||||
}
|
||||
|
||||
TEST_F(JsonObjectConversionTest, StdUnorderedMultiMap)
|
||||
{
|
||||
auto m1 = j1.get<std::unordered_multimap<std::string, int>>();
|
||||
auto m2 = j2.get<std::unordered_multimap<std::string, unsigned int>>();
|
||||
auto m3 = j3.get<std::unordered_multimap<std::string, double>>();
|
||||
auto m4 = j4.get<std::unordered_multimap<std::string, bool>>();
|
||||
//auto m5 = j5.get<std::unordered_multimap<std::string, std::string>>();
|
||||
//CHECK(m5["one"] == "eins");
|
||||
}
|
||||
|
||||
// exception in case of a non-object type
|
||||
TEST_F(JsonObjectConversionTest, Exception)
|
||||
{
|
||||
EXPECT_THROW_MSG((json().get<std::map<std::string, int>>()), json::type_error,
|
||||
"[json.exception.type_error.302] type must be object, but is null");
|
||||
}
|
||||
|
||||
class JsonArrayConversionTest : public ::testing::Test {
|
||||
protected:
|
||||
json j1 = {1, 2, 3, 4};
|
||||
json j2 = {1u, 2u, 3u, 4u};
|
||||
json j3 = {1.2, 2.3, 3.4, 4.5};
|
||||
json j4 = {true, false, true};
|
||||
json j5 = {"one", "two", "three"};
|
||||
};
|
||||
|
||||
TEST_F(JsonArrayConversionTest, StdList)
|
||||
{
|
||||
auto m1 = j1.get<std::list<int>>();
|
||||
auto m2 = j2.get<std::list<unsigned int>>();
|
||||
auto m3 = j3.get<std::list<double>>();
|
||||
auto m4 = j4.get<std::list<bool>>();
|
||||
auto m5 = j5.get<std::list<std::string>>();
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST_F(JsonArrayConversionTest, StdForwardList)
|
||||
{
|
||||
auto m1 = j1.get<std::forward_list<int>>();
|
||||
auto m2 = j2.get<std::forward_list<unsigned int>>();
|
||||
auto m3 = j3.get<std::forward_list<double>>();
|
||||
auto m4 = j4.get<std::forward_list<bool>>();
|
||||
auto m5 = j5.get<std::forward_list<std::string>>();
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_F(JsonArrayConversionTest, StdVector)
|
||||
{
|
||||
auto m1 = j1.get<std::vector<int>>();
|
||||
auto m2 = j2.get<std::vector<unsigned int>>();
|
||||
auto m3 = j3.get<std::vector<double>>();
|
||||
auto m4 = j4.get<std::vector<bool>>();
|
||||
auto m5 = j5.get<std::vector<std::string>>();
|
||||
}
|
||||
|
||||
TEST_F(JsonArrayConversionTest, StdDeque)
|
||||
{
|
||||
auto m1 = j1.get<std::deque<int>>();
|
||||
auto m2 = j2.get<std::deque<unsigned int>>();
|
||||
auto m3 = j2.get<std::deque<double>>();
|
||||
auto m4 = j4.get<std::deque<bool>>();
|
||||
auto m5 = j5.get<std::deque<std::string>>();
|
||||
}
|
||||
|
||||
TEST_F(JsonArrayConversionTest, StdSet)
|
||||
{
|
||||
auto m1 = j1.get<std::set<int>>();
|
||||
auto m2 = j2.get<std::set<unsigned int>>();
|
||||
auto m3 = j3.get<std::set<double>>();
|
||||
auto m4 = j4.get<std::set<bool>>();
|
||||
auto m5 = j5.get<std::set<std::string>>();
|
||||
}
|
||||
|
||||
TEST_F(JsonArrayConversionTest, StdUnorderedSet)
|
||||
{
|
||||
auto m1 = j1.get<std::unordered_set<int>>();
|
||||
auto m2 = j2.get<std::unordered_set<unsigned int>>();
|
||||
auto m3 = j3.get<std::unordered_set<double>>();
|
||||
auto m4 = j4.get<std::unordered_set<bool>>();
|
||||
auto m5 = j5.get<std::unordered_set<std::string>>();
|
||||
}
|
||||
|
||||
// exception in case of a non-object type
|
||||
TEST_F(JsonArrayConversionTest, Exception)
|
||||
{
|
||||
EXPECT_THROW_MSG((json().get<std::list<int>>()), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
EXPECT_THROW_MSG((json().get<std::vector<int>>()), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
EXPECT_THROW_MSG((json().get<std::vector<json>>()), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
EXPECT_THROW_MSG((json().get<std::list<json>>()), json::type_error,
|
||||
"[json.exception.type_error.302] type must be array, but is null");
|
||||
// does type really must be an array? or it rather must not be null?
|
||||
// that's what I thought when other test like this one broke
|
||||
}
|
||||
138
wpiutil/src/test/native/cpp/json/unit-deserialization.cpp
Normal file
138
wpiutil/src/test/native/cpp/json/unit-deserialization.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
#include "support/raw_istream.h"
|
||||
using wpi::json;
|
||||
|
||||
#include <valarray>
|
||||
|
||||
TEST(JsonDeserializationTest, SuccessfulStream)
|
||||
{
|
||||
std::string s = "[\"foo\",1,2,3,false,{\"one\":1}]";
|
||||
wpi::raw_mem_istream ss(s.data(), s.size());
|
||||
json j = json::parse(ss);
|
||||
ASSERT_EQ(j, json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||
}
|
||||
|
||||
TEST(JsonDeserializationTest, SuccessfulStringLiteral)
|
||||
{
|
||||
auto s = "[\"foo\",1,2,3,false,{\"one\":1}]";
|
||||
json j = json::parse(s);
|
||||
ASSERT_EQ(j, json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||
}
|
||||
|
||||
TEST(JsonDeserializationTest, SuccessfulStdString)
|
||||
{
|
||||
std::string s = "[\"foo\",1,2,3,false,{\"one\":1}]";
|
||||
json j = json::parse(s);
|
||||
ASSERT_EQ(j, json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||
}
|
||||
|
||||
TEST(JsonDeserializationTest, SuccessfulStreamOperator)
|
||||
{
|
||||
std::string s = "[\"foo\",1,2,3,false,{\"one\":1}]";
|
||||
wpi::raw_mem_istream ss(s.data(), s.size());
|
||||
json j;
|
||||
ss >> j;
|
||||
ASSERT_EQ(j, json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||
}
|
||||
|
||||
TEST(JsonDeserializationTest, SuccessfulUserStringLiteral)
|
||||
{
|
||||
ASSERT_EQ("[\"foo\",1,2,3,false,{\"one\":1}]"_json, json({"foo", 1, 2, 3, false, {{"one", 1}}}));
|
||||
}
|
||||
|
||||
TEST(JsonDeserializationTest, UnsuccessfulStream)
|
||||
{
|
||||
std::string s = "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||
wpi::raw_mem_istream ss(s.data(), s.size());
|
||||
ASSERT_THROW_MSG(json::parse(ss), json::parse_error,
|
||||
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'");
|
||||
}
|
||||
|
||||
TEST(JsonDeserializationTest, UnsuccessfulStdString)
|
||||
{
|
||||
std::string s = "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||
ASSERT_THROW_MSG(json::parse(s), json::parse_error,
|
||||
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'");
|
||||
}
|
||||
|
||||
TEST(JsonDeserializationTest, UnsuccessfulStreamOperator)
|
||||
{
|
||||
std::string s = "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||
wpi::raw_mem_istream ss(s.data(), s.size());
|
||||
json j;
|
||||
ASSERT_THROW_MSG(ss >> j, json::parse_error,
|
||||
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'");
|
||||
}
|
||||
|
||||
TEST(JsonDeserializationTest, UnsuccessfulUserStringLiteral)
|
||||
{
|
||||
ASSERT_THROW_MSG("[\"foo\",1,2,3,false,{\"one\":1}"_json, json::parse_error,
|
||||
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'");
|
||||
}
|
||||
|
||||
// these cases are required for 100% line coverage
|
||||
class JsonDeserializationErrorTest
|
||||
: public ::testing::TestWithParam<const char*> {};
|
||||
|
||||
TEST_P(JsonDeserializationErrorTest, ErrorCase)
|
||||
{
|
||||
ASSERT_THROW(json::parse(GetParam()), json::parse_error);
|
||||
}
|
||||
|
||||
static const char* error_cases[] = {
|
||||
"\"aaaaaa\\u",
|
||||
"\"aaaaaa\\u1",
|
||||
"\"aaaaaa\\u11111111",
|
||||
"\"aaaaaau11111111\\",
|
||||
"\"\x7F\xC1",
|
||||
"\"\x7F\xDF\x7F",
|
||||
"\"\x7F\xDF\xC0",
|
||||
"\"\x7F\xE0\x9F",
|
||||
"\"\x7F\xEF\xC0",
|
||||
"\"\x7F\xED\x7F",
|
||||
"\"\x7F\xF0\x8F",
|
||||
"\"\x7F\xF0\xC0",
|
||||
"\"\x7F\xF3\x7F",
|
||||
"\"\x7F\xF3\xC0",
|
||||
"\"\x7F\xF4\x7F",
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(JsonDeserializationErrorTests,
|
||||
JsonDeserializationErrorTest,
|
||||
::testing::ValuesIn(error_cases), );
|
||||
873
wpiutil/src/test/native/cpp/json/unit-element_access1.cpp
Normal file
873
wpiutil/src/test/native/cpp/json/unit-element_access1.cpp
Normal file
@@ -0,0 +1,873 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
class JsonElementArrayAccessTestBase {
|
||||
public:
|
||||
JsonElementArrayAccessTestBase() : j_const(j) {}
|
||||
|
||||
protected:
|
||||
json j = {1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}};
|
||||
const json j_const;
|
||||
};
|
||||
|
||||
class JsonElementArrayAccessTest : public ::testing::Test,
|
||||
public JsonElementArrayAccessTestBase {};
|
||||
|
||||
TEST_F(JsonElementArrayAccessTest, AtWithinBounds)
|
||||
{
|
||||
EXPECT_EQ(j.at(0), json(1));
|
||||
EXPECT_EQ(j.at(1), json(1u));
|
||||
EXPECT_EQ(j.at(2), json(true));
|
||||
EXPECT_EQ(j.at(3), json(nullptr));
|
||||
EXPECT_EQ(j.at(4), json("string"));
|
||||
EXPECT_EQ(j.at(5), json(42.23));
|
||||
EXPECT_EQ(j.at(6), json::object());
|
||||
EXPECT_EQ(j.at(7), json({1, 2, 3}));
|
||||
|
||||
EXPECT_EQ(j_const.at(0), json(1));
|
||||
EXPECT_EQ(j_const.at(1), json(1u));
|
||||
EXPECT_EQ(j_const.at(2), json(true));
|
||||
EXPECT_EQ(j_const.at(3), json(nullptr));
|
||||
EXPECT_EQ(j_const.at(4), json("string"));
|
||||
EXPECT_EQ(j_const.at(5), json(42.23));
|
||||
EXPECT_EQ(j_const.at(6), json::object());
|
||||
EXPECT_EQ(j_const.at(7), json({1, 2, 3}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayAccessTest, AtOutsideBounds)
|
||||
{
|
||||
EXPECT_THROW_MSG(j.at(8), json::out_of_range,
|
||||
"[json.exception.out_of_range.401] array index 8 is out of range");
|
||||
EXPECT_THROW_MSG(j_const.at(8), json::out_of_range,
|
||||
"[json.exception.out_of_range.401] array index 8 is out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayAtAccessTest, Null)
|
||||
{
|
||||
json j_nonarray(json::value_t::null);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with null");
|
||||
EXPECT_THROW_MSG(j_nonarray_const.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayAtAccessTest, Boolean)
|
||||
{
|
||||
json j_nonarray(json::value_t::boolean);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with boolean");
|
||||
EXPECT_THROW_MSG(j_nonarray_const.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with boolean");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayAtAccessTest, String)
|
||||
{
|
||||
json j_nonarray(json::value_t::string);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with string");
|
||||
EXPECT_THROW_MSG(j_nonarray_const.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with string");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayAtAccessTest, Object)
|
||||
{
|
||||
json j_nonarray(json::value_t::object);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with object");
|
||||
EXPECT_THROW_MSG(j_nonarray_const.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with object");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayAtAccessTest, Integer)
|
||||
{
|
||||
json j_nonarray(json::value_t::number_integer);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
EXPECT_THROW_MSG(j_nonarray_const.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayAtAccessTest, Unsigned)
|
||||
{
|
||||
json j_nonarray(json::value_t::number_unsigned);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
EXPECT_THROW_MSG(j_nonarray_const.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayAtAccessTest, Float)
|
||||
{
|
||||
json j_nonarray(json::value_t::number_float);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
EXPECT_THROW_MSG(j_nonarray_const.at(0), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayAccessTest, FrontAndBack)
|
||||
{
|
||||
EXPECT_EQ(j.front(), json(1));
|
||||
EXPECT_EQ(j_const.front(), json(1));
|
||||
EXPECT_EQ(j.back(), json({1, 2, 3}));
|
||||
EXPECT_EQ(j_const.back(), json({1, 2, 3}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayAccessTest, OperatorWithinBounds)
|
||||
{
|
||||
EXPECT_EQ(j[0], json(1));
|
||||
EXPECT_EQ(j[1], json(1u));
|
||||
EXPECT_EQ(j[2], json(true));
|
||||
EXPECT_EQ(j[3], json(nullptr));
|
||||
EXPECT_EQ(j[4], json("string"));
|
||||
EXPECT_EQ(j[5], json(42.23));
|
||||
EXPECT_EQ(j[6], json::object());
|
||||
EXPECT_EQ(j[7], json({1, 2, 3}));
|
||||
|
||||
EXPECT_EQ(j_const[0], json(1));
|
||||
EXPECT_EQ(j_const[1], json(1u));
|
||||
EXPECT_EQ(j_const[2], json(true));
|
||||
EXPECT_EQ(j_const[3], json(nullptr));
|
||||
EXPECT_EQ(j_const[4], json("string"));
|
||||
EXPECT_EQ(j_const[5], json(42.23));
|
||||
EXPECT_EQ(j_const[6], json::object());
|
||||
EXPECT_EQ(j_const[7], json({1, 2, 3}));
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOperatorAccessTest, NullStandard)
|
||||
{
|
||||
json j_nonarray(json::value_t::null);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_NO_THROW(j_nonarray[0]);
|
||||
EXPECT_THROW_MSG(j_nonarray_const[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with null");
|
||||
}
|
||||
|
||||
// implicit transformation to properly filled array
|
||||
TEST(JsonElementNonArrayOperatorAccessTest, NullImplicitFilled)
|
||||
{
|
||||
json j_nonarray;
|
||||
j_nonarray[3] = 42;
|
||||
EXPECT_EQ(j_nonarray, json({nullptr, nullptr, nullptr, 42}));
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOperatorAccessTest, Boolean)
|
||||
{
|
||||
json j_nonarray(json::value_t::boolean);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with boolean");
|
||||
EXPECT_THROW_MSG(j_nonarray_const[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with boolean");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOperatorAccessTest, String)
|
||||
{
|
||||
json j_nonarray(json::value_t::string);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with string");
|
||||
EXPECT_THROW_MSG(j_nonarray_const[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with string");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOperatorAccessTest, Object)
|
||||
{
|
||||
json j_nonarray(json::value_t::object);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with object");
|
||||
EXPECT_THROW_MSG(j_nonarray_const[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with object");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOperatorAccessTest, Integer)
|
||||
{
|
||||
json j_nonarray(json::value_t::number_integer);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_nonarray_const[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOperatorAccessTest, Unsigned)
|
||||
{
|
||||
json j_nonarray(json::value_t::number_unsigned);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_nonarray_const[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOperatorAccessTest, Float)
|
||||
{
|
||||
json j_nonarray(json::value_t::number_float);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_THROW_MSG(j_nonarray[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_nonarray_const[0], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
}
|
||||
|
||||
class JsonElementArrayRemoveTest : public ::testing::Test,
|
||||
public JsonElementArrayAccessTestBase {};
|
||||
|
||||
|
||||
// remove element by index
|
||||
TEST_F(JsonElementArrayRemoveTest, Index0)
|
||||
{
|
||||
j.erase(0);
|
||||
EXPECT_EQ(j, json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, Index1)
|
||||
{
|
||||
j.erase(1);
|
||||
EXPECT_EQ(j, json({1, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, Index2)
|
||||
{
|
||||
j.erase(2);
|
||||
EXPECT_EQ(j, json({1, 1u, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, Index3)
|
||||
{
|
||||
j.erase(3);
|
||||
EXPECT_EQ(j, json({1, 1u, true, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, Index4)
|
||||
{
|
||||
j.erase(4);
|
||||
EXPECT_EQ(j, json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, Index5)
|
||||
{
|
||||
j.erase(5);
|
||||
EXPECT_EQ(j, json({1, 1u, true, nullptr, "string", json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, Index6)
|
||||
{
|
||||
j.erase(6);
|
||||
EXPECT_EQ(j, json({1, 1u, true, nullptr, "string", 42.23, {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, Index7)
|
||||
{
|
||||
j.erase(7);
|
||||
EXPECT_EQ(j, json({1, 1u, true, nullptr, "string", 42.23, json::object()}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, Index8)
|
||||
{
|
||||
EXPECT_THROW_MSG(j.erase(8), json::out_of_range,
|
||||
"[json.exception.out_of_range.401] array index 8 is out of range");
|
||||
}
|
||||
|
||||
// erase(begin())
|
||||
TEST_F(JsonElementArrayRemoveTest, Begin)
|
||||
{
|
||||
j.erase(j.begin());
|
||||
EXPECT_EQ(j, json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, BeginConst)
|
||||
{
|
||||
j.erase(j.cbegin());
|
||||
EXPECT_EQ(j, json({1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
// erase(begin(), end())
|
||||
TEST_F(JsonElementArrayRemoveTest, BeginEnd)
|
||||
{
|
||||
j.erase(j.begin(), j.end());
|
||||
EXPECT_EQ(j, json::array());
|
||||
}
|
||||
TEST_F(JsonElementArrayRemoveTest, BeginEndConst)
|
||||
{
|
||||
j.erase(j.cbegin(), j.cend());
|
||||
EXPECT_EQ(j, json::array());
|
||||
}
|
||||
|
||||
// erase(begin(), begin())
|
||||
TEST_F(JsonElementArrayRemoveTest, BeginBegin)
|
||||
{
|
||||
j.erase(j.begin(), j.begin());
|
||||
EXPECT_EQ(j, json({1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, BeginBeginConst)
|
||||
{
|
||||
j.erase(j.cbegin(), j.cbegin());
|
||||
EXPECT_EQ(j, json({1, 1u, true, nullptr, "string", 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
// erase at offset
|
||||
TEST_F(JsonElementArrayRemoveTest, Offset)
|
||||
{
|
||||
json::iterator it = j.begin() + 4;
|
||||
j.erase(it);
|
||||
EXPECT_EQ(j, json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, OffsetConst)
|
||||
{
|
||||
json::const_iterator it = j.cbegin() + 4;
|
||||
j.erase(it);
|
||||
EXPECT_EQ(j, json({1, 1u, true, nullptr, 42.23, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
// erase subrange
|
||||
TEST_F(JsonElementArrayRemoveTest, Subrange)
|
||||
{
|
||||
j.erase(j.begin() + 3, j.begin() + 6);
|
||||
EXPECT_EQ(j, json({1, 1u, true, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, SubrangeConst)
|
||||
{
|
||||
j.erase(j.cbegin() + 3, j.cbegin() + 6);
|
||||
EXPECT_EQ(j, json({1, 1u, true, json::object(), {1, 2, 3}}));
|
||||
}
|
||||
|
||||
// different arrays
|
||||
TEST_F(JsonElementArrayRemoveTest, Different)
|
||||
{
|
||||
json j2 = {"foo", "bar"};
|
||||
EXPECT_THROW_MSG(j.erase(j2.begin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.202] iterator does not fit current value");
|
||||
EXPECT_THROW_MSG(j.erase(j.begin(), j2.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
EXPECT_THROW_MSG(j.erase(j2.begin(), j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
EXPECT_THROW_MSG(j.erase(j2.begin(), j2.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
}
|
||||
|
||||
TEST_F(JsonElementArrayRemoveTest, DifferentConst)
|
||||
{
|
||||
json j2 = {"foo", "bar"};
|
||||
EXPECT_THROW_MSG(j.erase(j2.cbegin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.202] iterator does not fit current value");
|
||||
EXPECT_THROW_MSG(j.erase(j.cbegin(), j2.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
EXPECT_THROW_MSG(j.erase(j2.cbegin(), j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
EXPECT_THROW_MSG(j.erase(j2.cbegin(), j2.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
}
|
||||
|
||||
// remove element by index in non-array type
|
||||
TEST(JsonElementNonArrayIndexRemoveTest, Null)
|
||||
{
|
||||
json j_nonobject(json::value_t::null);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase(0), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayIndexRemoveTest, Boolean)
|
||||
{
|
||||
json j_nonobject(json::value_t::boolean);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase(0), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with boolean");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayIndexRemoveTest, String)
|
||||
{
|
||||
json j_nonobject(json::value_t::string);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase(0), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with string");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayIndexRemoveTest, Object)
|
||||
{
|
||||
json j_nonobject(json::value_t::object);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase(0), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with object");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayIndexRemoveTest, Integer)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_integer);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase(0), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayIndexRemoveTest, Unsigned)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_unsigned);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase(0), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayIndexRemoveTest, Float)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_float);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase(0), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, Null)
|
||||
{
|
||||
json j;
|
||||
EXPECT_THROW_MSG(j.front(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
EXPECT_THROW_MSG(j.back(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, NullConst)
|
||||
{
|
||||
const json j{};
|
||||
EXPECT_THROW_MSG(j.front(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
EXPECT_THROW_MSG(j.back(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, String)
|
||||
{
|
||||
json j = "foo";
|
||||
EXPECT_EQ(j.front(), j);
|
||||
EXPECT_EQ(j.back(), j);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, StringConst)
|
||||
{
|
||||
const json j = "bar";
|
||||
EXPECT_EQ(j.front(), j);
|
||||
EXPECT_EQ(j.back(), j);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, Boolean)
|
||||
{
|
||||
json j = false;
|
||||
EXPECT_EQ(j.front(), j);
|
||||
EXPECT_EQ(j.back(), j);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, BooleanConst)
|
||||
{
|
||||
const json j = true;
|
||||
EXPECT_EQ(j.front(), j);
|
||||
EXPECT_EQ(j.back(), j);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, Integer)
|
||||
{
|
||||
json j = 17;
|
||||
EXPECT_EQ(j.front(), j);
|
||||
EXPECT_EQ(j.back(), j);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, IntegerConst)
|
||||
{
|
||||
const json j = 17;
|
||||
EXPECT_EQ(j.front(), j);
|
||||
EXPECT_EQ(j.back(), j);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, Unsigned)
|
||||
{
|
||||
json j = 17u;
|
||||
EXPECT_EQ(j.front(), j);
|
||||
EXPECT_EQ(j.back(), j);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, UnsignedConst)
|
||||
{
|
||||
const json j = 17u;
|
||||
EXPECT_EQ(j.front(), j);
|
||||
EXPECT_EQ(j.back(), j);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, Float)
|
||||
{
|
||||
json j = 23.42;
|
||||
EXPECT_EQ(j.front(), j);
|
||||
EXPECT_EQ(j.back(), j);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayFrontBackAccessTest, FloatConst)
|
||||
{
|
||||
const json j = 23.42;
|
||||
EXPECT_EQ(j.front(), j);
|
||||
EXPECT_EQ(j.back(), j);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, Null)
|
||||
{
|
||||
json j;
|
||||
EXPECT_THROW_MSG(j.erase(j.begin()), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, NullConst)
|
||||
{
|
||||
json j;
|
||||
EXPECT_THROW_MSG(j.erase(j.cbegin()), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, String)
|
||||
{
|
||||
json j = "foo";
|
||||
j.erase(j.begin());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, StringConst)
|
||||
{
|
||||
json j = "bar";
|
||||
j.erase(j.cbegin());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, Boolean)
|
||||
{
|
||||
json j = false;
|
||||
j.erase(j.begin());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, BooleanConst)
|
||||
{
|
||||
json j = true;
|
||||
j.erase(j.cbegin());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, Integer)
|
||||
{
|
||||
json j = 17;
|
||||
j.erase(j.begin());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, IntegerConst)
|
||||
{
|
||||
json j = 17;
|
||||
j.erase(j.cbegin());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, Unsigned)
|
||||
{
|
||||
json j = 17u;
|
||||
j.erase(j.begin());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, UnsignedConst)
|
||||
{
|
||||
json j = 17u;
|
||||
j.erase(j.cbegin());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, Float)
|
||||
{
|
||||
json j = 23.42;
|
||||
j.erase(j.begin());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneValidIteratorRemoveTest, FloatConst)
|
||||
{
|
||||
json j = 23.42;
|
||||
j.erase(j.cbegin());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneInvalidIteratorRemoveTest, String)
|
||||
{
|
||||
json j = "foo";
|
||||
EXPECT_THROW_MSG(j.erase(j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.205] iterator out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneInvalidIteratorRemoveTest, StringConst)
|
||||
{
|
||||
json j = "bar";
|
||||
EXPECT_THROW_MSG(j.erase(j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.205] iterator out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneInvalidIteratorRemoveTest, Boolean)
|
||||
{
|
||||
json j = false;
|
||||
EXPECT_THROW_MSG(j.erase(j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.205] iterator out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneInvalidIteratorRemoveTest, BooleanConst)
|
||||
{
|
||||
json j = true;
|
||||
EXPECT_THROW_MSG(j.erase(j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.205] iterator out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneInvalidIteratorRemoveTest, Integer)
|
||||
{
|
||||
json j = 17;
|
||||
EXPECT_THROW_MSG(j.erase(j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.205] iterator out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneInvalidIteratorRemoveTest, IntegerConst)
|
||||
{
|
||||
json j = 17;
|
||||
EXPECT_THROW_MSG(j.erase(j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.205] iterator out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneInvalidIteratorRemoveTest, Unsigned)
|
||||
{
|
||||
json j = 17u;
|
||||
EXPECT_THROW_MSG(j.erase(j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.205] iterator out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneInvalidIteratorRemoveTest, UnsignedConst)
|
||||
{
|
||||
json j = 17u;
|
||||
EXPECT_THROW_MSG(j.erase(j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.205] iterator out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneInvalidIteratorRemoveTest, Float)
|
||||
{
|
||||
json j = 23.42;
|
||||
EXPECT_THROW_MSG(j.erase(j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.205] iterator out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayOneInvalidIteratorRemoveTest, FloatConst)
|
||||
{
|
||||
json j = 23.42;
|
||||
EXPECT_THROW_MSG(j.erase(j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.205] iterator out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, Null)
|
||||
{
|
||||
json j;
|
||||
EXPECT_THROW_MSG(j.erase(j.begin(), j.end()), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, NullConst)
|
||||
{
|
||||
json j;
|
||||
EXPECT_THROW_MSG(j.erase(j.cbegin(), j.cend()), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, String)
|
||||
{
|
||||
json j = "foo";
|
||||
j.erase(j.begin(), j.end());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, StringConst)
|
||||
{
|
||||
json j = "bar";
|
||||
j.erase(j.cbegin(), j.cend());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, Boolean)
|
||||
{
|
||||
json j = false;
|
||||
j.erase(j.begin(), j.end());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, BooleanConst)
|
||||
{
|
||||
json j = true;
|
||||
j.erase(j.cbegin(), j.cend());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, Integer)
|
||||
{
|
||||
json j = 17;
|
||||
j.erase(j.begin(), j.end());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, IntegerConst)
|
||||
{
|
||||
json j = 17;
|
||||
j.erase(j.cbegin(), j.cend());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, Unsigned)
|
||||
{
|
||||
json j = 17u;
|
||||
j.erase(j.begin(), j.end());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, UnsignedConst)
|
||||
{
|
||||
json j = 17u;
|
||||
j.erase(j.cbegin(), j.cend());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, Float)
|
||||
{
|
||||
json j = 23.42;
|
||||
j.erase(j.begin(), j.end());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoValidIteratorRemoveTest, FloatConst)
|
||||
{
|
||||
json j = 23.42;
|
||||
j.erase(j.cbegin(), j.cend());
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoInvalidIteratorRemoveTest, String)
|
||||
{
|
||||
json j = "foo";
|
||||
EXPECT_THROW_MSG(j.erase(j.end(), j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
EXPECT_THROW_MSG(j.erase(j.begin(), j.begin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoInvalidIteratorRemoveTest, StringConst)
|
||||
{
|
||||
json j = "bar";
|
||||
EXPECT_THROW_MSG(j.erase(j.cend(), j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
EXPECT_THROW_MSG(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoInvalidIteratorRemoveTest, Boolean)
|
||||
{
|
||||
json j = false;
|
||||
EXPECT_THROW_MSG(j.erase(j.end(), j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
EXPECT_THROW_MSG(j.erase(j.begin(), j.begin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoInvalidIteratorRemoveTest, BooleanConst)
|
||||
{
|
||||
json j = true;
|
||||
EXPECT_THROW_MSG(j.erase(j.cend(), j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
EXPECT_THROW_MSG(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoInvalidIteratorRemoveTest, Integer)
|
||||
{
|
||||
json j = 17;
|
||||
EXPECT_THROW_MSG(j.erase(j.end(), j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
EXPECT_THROW_MSG(j.erase(j.begin(), j.begin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoInvalidIteratorRemoveTest, IntegerConst)
|
||||
{
|
||||
json j = 17;
|
||||
EXPECT_THROW_MSG(j.erase(j.cend(), j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
EXPECT_THROW_MSG(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoInvalidIteratorRemoveTest, Unsigned)
|
||||
{
|
||||
json j = 17u;
|
||||
EXPECT_THROW_MSG(j.erase(j.end(), j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
EXPECT_THROW_MSG(j.erase(j.begin(), j.begin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoInvalidIteratorRemoveTest, UnsignedConst)
|
||||
{
|
||||
json j = 17u;
|
||||
EXPECT_THROW_MSG(j.erase(j.cend(), j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
EXPECT_THROW_MSG(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoInvalidIteratorRemoveTest, Float)
|
||||
{
|
||||
json j = 23.42;
|
||||
EXPECT_THROW_MSG(j.erase(j.end(), j.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
EXPECT_THROW_MSG(j.erase(j.begin(), j.begin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonArrayTwoInvalidIteratorRemoveTest, FloatConst)
|
||||
{
|
||||
json j = 23.42;
|
||||
EXPECT_THROW_MSG(j.erase(j.cend(), j.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
EXPECT_THROW_MSG(j.erase(j.cbegin(), j.cbegin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.204] iterators out of range");
|
||||
}
|
||||
923
wpiutil/src/test/native/cpp/json/unit-element_access2.cpp
Normal file
923
wpiutil/src/test/native/cpp/json/unit-element_access2.cpp
Normal file
@@ -0,0 +1,923 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
class JsonElementObjectAccessTestBase {
|
||||
public:
|
||||
JsonElementObjectAccessTestBase() : j_const(j) {}
|
||||
|
||||
protected:
|
||||
json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", json::object()}, {"array", {1, 2, 3}}};
|
||||
const json j_const;
|
||||
};
|
||||
|
||||
class JsonElementObjectAccessTest : public ::testing::Test,
|
||||
public JsonElementObjectAccessTestBase {};
|
||||
|
||||
TEST_F(JsonElementObjectAccessTest, AtWithinBounds)
|
||||
{
|
||||
EXPECT_EQ(j.at("integer"), json(1));
|
||||
EXPECT_EQ(j.at("unsigned"), json(1u));
|
||||
EXPECT_EQ(j.at("boolean"), json(true));
|
||||
EXPECT_EQ(j.at("null"), json(nullptr));
|
||||
EXPECT_EQ(j.at("string"), json("hello world"));
|
||||
EXPECT_EQ(j.at("floating"), json(42.23));
|
||||
EXPECT_EQ(j.at("object"), json::object());
|
||||
EXPECT_EQ(j.at("array"), json({1, 2, 3}));
|
||||
|
||||
EXPECT_EQ(j_const.at("integer"), json(1));
|
||||
EXPECT_EQ(j_const.at("unsigned"), json(1u));
|
||||
EXPECT_EQ(j_const.at("boolean"), json(true));
|
||||
EXPECT_EQ(j_const.at("null"), json(nullptr));
|
||||
EXPECT_EQ(j_const.at("string"), json("hello world"));
|
||||
EXPECT_EQ(j_const.at("floating"), json(42.23));
|
||||
EXPECT_EQ(j_const.at("object"), json::object());
|
||||
EXPECT_EQ(j_const.at("array"), json({1, 2, 3}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectAccessTest, AtOutsideBounds)
|
||||
{
|
||||
EXPECT_THROW_MSG(j.at("foo"), json::out_of_range,
|
||||
"[json.exception.out_of_range.403] key 'foo' not found");
|
||||
EXPECT_THROW_MSG(j_const.at("foo"), json::out_of_range,
|
||||
"[json.exception.out_of_range.403] key 'foo' not found");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectAtAccessTest, Null)
|
||||
{
|
||||
json j_nonobject(json::value_t::null);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with null");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectAtAccessTest, Boolean)
|
||||
{
|
||||
json j_nonobject(json::value_t::boolean);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with boolean");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with boolean");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectAtAccessTest, String)
|
||||
{
|
||||
json j_nonobject(json::value_t::string);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with string");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with string");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectAtAccessTest, Array)
|
||||
{
|
||||
json j_nonobject(json::value_t::array);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with array");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with array");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectAtAccessTest, Integer)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_integer);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectAtAccessTest, Unsigned)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_unsigned);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectAtAccessTest, Float)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_float);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.at("foo"), json::type_error,
|
||||
"[json.exception.type_error.304] cannot use at() with number");
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectAccessTest, KeyValueExist)
|
||||
{
|
||||
EXPECT_EQ(j.value("integer", 2), 1);
|
||||
EXPECT_LT(std::fabs(j.value("integer", 1.0) - 1), 0.001);
|
||||
EXPECT_EQ(j.value("unsigned", 2), 1);
|
||||
EXPECT_LT(std::fabs(j.value("unsigned", 1.0) - 1), 0.001);
|
||||
EXPECT_EQ(j.value("null", json(1)), json());
|
||||
EXPECT_EQ(j.value("boolean", false), true);
|
||||
EXPECT_EQ(j.value("string", "bar"), "hello world");
|
||||
EXPECT_EQ(j.value("string", std::string("bar")), "hello world");
|
||||
EXPECT_LT(std::fabs(j.value("floating", 12.34) - 42.23), 0.001);
|
||||
EXPECT_EQ(j.value("floating", 12), 42);
|
||||
EXPECT_EQ(j.value("object", json({{"foo", "bar"}})), json::object());
|
||||
EXPECT_EQ(j.value("array", json({10, 100})), json({1, 2, 3}));
|
||||
|
||||
EXPECT_EQ(j_const.value("integer", 2), 1);
|
||||
EXPECT_LT(std::fabs(j_const.value("integer", 1.0) - 1), 0.001);
|
||||
EXPECT_EQ(j_const.value("unsigned", 2), 1);
|
||||
EXPECT_LT(std::fabs(j_const.value("unsigned", 1.0) - 1), 0.001);
|
||||
EXPECT_EQ(j_const.value("boolean", false), true);
|
||||
EXPECT_EQ(j_const.value("string", "bar"), "hello world");
|
||||
EXPECT_EQ(j_const.value("string", std::string("bar")), "hello world");
|
||||
EXPECT_LT(std::fabs(j_const.value("floating", 12.34) - 42.23), 0.001);
|
||||
EXPECT_EQ(j_const.value("floating", 12), 42);
|
||||
EXPECT_EQ(j_const.value("object", json({{"foo", "bar"}})), json::object());
|
||||
EXPECT_EQ(j_const.value("array", json({10, 100})), json({1, 2, 3}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectAccessTest, KeyValueNotExist)
|
||||
{
|
||||
EXPECT_EQ(j.value("_", 2), 2);
|
||||
EXPECT_EQ(j.value("_", 2u), 2u);
|
||||
EXPECT_EQ(j.value("_", false), false);
|
||||
EXPECT_EQ(j.value("_", "bar"), "bar");
|
||||
EXPECT_LT(std::fabs(j.value("_", 12.34) - 12.34), 0.001);
|
||||
EXPECT_EQ(j.value("_", json({{"foo", "bar"}})), json({{"foo", "bar"}}));
|
||||
EXPECT_EQ(j.value("_", json({10, 100})), json({10, 100}));
|
||||
|
||||
EXPECT_EQ(j_const.value("_", 2), 2);
|
||||
EXPECT_EQ(j_const.value("_", 2u), 2u);
|
||||
EXPECT_EQ(j_const.value("_", false), false);
|
||||
EXPECT_EQ(j_const.value("_", "bar"), "bar");
|
||||
EXPECT_LT(std::fabs(j_const.value("_", 12.34) - 12.34), 0.001);
|
||||
EXPECT_EQ(j_const.value("_", json({{"foo", "bar"}})), json({{"foo", "bar"}}));
|
||||
EXPECT_EQ(j_const.value("_", json({10, 100})), json({10, 100}));
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyValueAccessTest, Null)
|
||||
{
|
||||
json j_nonobject(json::value_t::null);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with null");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyValueAccessTest, Boolean)
|
||||
{
|
||||
json j_nonobject(json::value_t::boolean);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with boolean");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with boolean");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyValueAccessTest, String)
|
||||
{
|
||||
json j_nonobject(json::value_t::string);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with string");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with string");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyValueAccessTest, Array)
|
||||
{
|
||||
json j_nonobject(json::value_t::array);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with array");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with array");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyValueAccessTest, Integer)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_integer);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyValueAccessTest, Unsigned)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_unsigned);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyValueAccessTest, Float)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_float);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("foo", 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectAccessTest, PointerValueExist)
|
||||
{
|
||||
EXPECT_EQ(j.value("/integer"_json_pointer, 2), 1);
|
||||
EXPECT_LT(std::fabs(j.value("/integer"_json_pointer, 1.0) - 1), 0.001);
|
||||
EXPECT_EQ(j.value("/unsigned"_json_pointer, 2), 1);
|
||||
EXPECT_LT(std::fabs(j.value("/unsigned"_json_pointer, 1.0) - 1), 0.001);
|
||||
EXPECT_EQ(j.value("/null"_json_pointer, json(1)), json());
|
||||
EXPECT_EQ(j.value("/boolean"_json_pointer, false), true);
|
||||
EXPECT_EQ(j.value("/string"_json_pointer, "bar"), "hello world");
|
||||
EXPECT_EQ(j.value("/string"_json_pointer, std::string("bar")), "hello world");
|
||||
EXPECT_LT(std::fabs(j.value("/floating"_json_pointer, 12.34) - 42.23), 0.001);
|
||||
EXPECT_EQ(j.value("/floating"_json_pointer, 12), 42);
|
||||
EXPECT_EQ(j.value("/object"_json_pointer, json({{"foo", "bar"}})), json::object());
|
||||
EXPECT_EQ(j.value("/array"_json_pointer, json({10, 100})), json({1, 2, 3}));
|
||||
|
||||
EXPECT_EQ(j_const.value("/integer"_json_pointer, 2), 1);
|
||||
EXPECT_LT(std::fabs(j_const.value("/integer"_json_pointer, 1.0) - 1), 0.001);
|
||||
EXPECT_EQ(j_const.value("/unsigned"_json_pointer, 2), 1);
|
||||
EXPECT_LT(std::fabs(j_const.value("/unsigned"_json_pointer, 1.0) - 1), 0.001);
|
||||
EXPECT_EQ(j_const.value("/boolean"_json_pointer, false), true);
|
||||
EXPECT_EQ(j_const.value("/string"_json_pointer, "bar"), "hello world");
|
||||
EXPECT_EQ(j_const.value("/string"_json_pointer, std::string("bar")), "hello world");
|
||||
EXPECT_LT(std::fabs(j_const.value("/floating"_json_pointer, 12.34) - 42.23), 0.001);
|
||||
EXPECT_EQ(j_const.value("/floating"_json_pointer, 12), 42);
|
||||
EXPECT_EQ(j_const.value("/object"_json_pointer, json({{"foo", "bar"}})), json::object());
|
||||
EXPECT_EQ(j_const.value("/array"_json_pointer, json({10, 100})), json({1, 2, 3}));
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectPointerValueAccessTest, Null)
|
||||
{
|
||||
json j_nonobject(json::value_t::null);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with null");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectPointerValueAccessTest, Boolean)
|
||||
{
|
||||
json j_nonobject(json::value_t::boolean);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with boolean");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with boolean");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectPointerValueAccessTest, String)
|
||||
{
|
||||
json j_nonobject(json::value_t::string);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with string");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with string");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectPointerValueAccessTest, Array)
|
||||
{
|
||||
json j_nonobject(json::value_t::array);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with array");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with array");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectPointerValueAccessTest, Integer)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_integer);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectPointerValueAccessTest, Unsigned)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_unsigned);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectPointerValueAccessTest, Float)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_float);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
EXPECT_THROW_MSG(j_nonobject_const.value("/foo"_json_pointer, 1), json::type_error,
|
||||
"[json.exception.type_error.306] cannot use value() with number");
|
||||
}
|
||||
#if 0
|
||||
TEST_F(JsonElementObjectAccessTest, FrontAndBack)
|
||||
{
|
||||
// "array" is the smallest key
|
||||
EXPECT_EQ(j.front(), json({1, 2, 3}));
|
||||
EXPECT_EQ(j_const.front(), json({1, 2, 3}));
|
||||
// "unsigned" is the largest key
|
||||
EXPECT_EQ(j.back(), json(1u));
|
||||
EXPECT_EQ(j_const.back(), json(1u));
|
||||
}
|
||||
#endif
|
||||
TEST_F(JsonElementObjectAccessTest, OperatorWithinBounds)
|
||||
{
|
||||
EXPECT_EQ(j["integer"], json(1));
|
||||
EXPECT_EQ(j[json::object_t::key_type("integer")], j["integer"]);
|
||||
|
||||
EXPECT_EQ(j["unsigned"], json(1u));
|
||||
EXPECT_EQ(j[json::object_t::key_type("unsigned")], j["unsigned"]);
|
||||
|
||||
EXPECT_EQ(j["boolean"], json(true));
|
||||
EXPECT_EQ(j[json::object_t::key_type("boolean")], j["boolean"]);
|
||||
|
||||
EXPECT_EQ(j["null"], json(nullptr));
|
||||
EXPECT_EQ(j[json::object_t::key_type("null")], j["null"]);
|
||||
|
||||
EXPECT_EQ(j["string"], json("hello world"));
|
||||
EXPECT_EQ(j[json::object_t::key_type("string")], j["string"]);
|
||||
|
||||
EXPECT_EQ(j["floating"], json(42.23));
|
||||
EXPECT_EQ(j[json::object_t::key_type("floating")], j["floating"]);
|
||||
|
||||
EXPECT_EQ(j["object"], json::object());
|
||||
EXPECT_EQ(j[json::object_t::key_type("object")], j["object"]);
|
||||
|
||||
EXPECT_EQ(j["array"], json({1, 2, 3}));
|
||||
EXPECT_EQ(j[json::object_t::key_type("array")], j["array"]);
|
||||
|
||||
EXPECT_EQ(j_const["integer"], json(1));
|
||||
EXPECT_EQ(j_const[json::object_t::key_type("integer")], j["integer"]);
|
||||
|
||||
EXPECT_EQ(j_const["boolean"], json(true));
|
||||
EXPECT_EQ(j_const[json::object_t::key_type("boolean")], j["boolean"]);
|
||||
|
||||
EXPECT_EQ(j_const["null"], json(nullptr));
|
||||
EXPECT_EQ(j_const[json::object_t::key_type("null")], j["null"]);
|
||||
|
||||
EXPECT_EQ(j_const["string"], json("hello world"));
|
||||
EXPECT_EQ(j_const[json::object_t::key_type("string")], j["string"]);
|
||||
|
||||
EXPECT_EQ(j_const["floating"], json(42.23));
|
||||
EXPECT_EQ(j_const[json::object_t::key_type("floating")], j["floating"]);
|
||||
|
||||
EXPECT_EQ(j_const["object"], json::object());
|
||||
EXPECT_EQ(j_const[json::object_t::key_type("object")], j["object"]);
|
||||
|
||||
EXPECT_EQ(j_const["array"], json({1, 2, 3}));
|
||||
EXPECT_EQ(j_const[json::object_t::key_type("array")], j["array"]);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectOperatorAccessTest, Null)
|
||||
{
|
||||
json j_nonobject(json::value_t::null);
|
||||
json j_nonobject2(json::value_t::null);
|
||||
const json j_const_nonobject(j_nonobject);
|
||||
EXPECT_NO_THROW(j_nonobject["foo"]);
|
||||
EXPECT_NO_THROW(j_nonobject2[json::object_t::key_type("foo")]);
|
||||
EXPECT_THROW_MSG(j_const_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with null");
|
||||
EXPECT_THROW_MSG(j_const_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectOperatorAccessTest, Boolean)
|
||||
{
|
||||
json j_nonobject(json::value_t::boolean);
|
||||
const json j_const_nonobject(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with boolean");
|
||||
EXPECT_THROW_MSG(j_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with boolean");
|
||||
EXPECT_THROW_MSG(j_const_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with boolean");
|
||||
EXPECT_THROW_MSG(j_const_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with boolean");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectOperatorAccessTest, String)
|
||||
{
|
||||
json j_nonobject(json::value_t::string);
|
||||
const json j_const_nonobject(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with string");
|
||||
EXPECT_THROW_MSG(j_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with string");
|
||||
EXPECT_THROW_MSG(j_const_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with string");
|
||||
EXPECT_THROW_MSG(j_const_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with string");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectOperatorAccessTest, Array)
|
||||
{
|
||||
json j_nonobject(json::value_t::array);
|
||||
const json j_const_nonobject(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with array");
|
||||
EXPECT_THROW_MSG(j_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with array");
|
||||
EXPECT_THROW_MSG(j_const_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with array");
|
||||
EXPECT_THROW_MSG(j_const_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with array");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectOperatorAccessTest, Integer)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_integer);
|
||||
const json j_const_nonobject(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_const_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_const_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectOperatorAccessTest, Unsigned)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_unsigned);
|
||||
const json j_const_nonobject(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_const_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_const_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectOperatorAccessTest, Float)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_float);
|
||||
const json j_const_nonobject(j_nonobject);
|
||||
EXPECT_THROW_MSG(j_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_const_nonobject["foo"], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
EXPECT_THROW_MSG(j_const_nonobject[json::object_t::key_type("foo")], json::type_error,
|
||||
"[json.exception.type_error.305] cannot use operator[] with number");
|
||||
}
|
||||
|
||||
class JsonElementObjectRemoveTest : public ::testing::Test,
|
||||
public JsonElementObjectAccessTestBase {};
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, Key)
|
||||
{
|
||||
EXPECT_NE(j.find("integer"), j.end());
|
||||
EXPECT_EQ(j.erase("integer"), 1u);
|
||||
EXPECT_EQ(j.find("integer"), j.end());
|
||||
EXPECT_EQ(j.erase("integer"), 0u);
|
||||
|
||||
EXPECT_NE(j.find("unsigned"), j.end());
|
||||
EXPECT_EQ(j.erase("unsigned"), 1u);
|
||||
EXPECT_EQ(j.find("unsigned"), j.end());
|
||||
EXPECT_EQ(j.erase("unsigned"), 0u);
|
||||
|
||||
EXPECT_NE(j.find("boolean"), j.end());
|
||||
EXPECT_EQ(j.erase("boolean"), 1u);
|
||||
EXPECT_EQ(j.find("boolean"), j.end());
|
||||
EXPECT_EQ(j.erase("boolean"), 0u);
|
||||
|
||||
EXPECT_NE(j.find("null"), j.end());
|
||||
EXPECT_EQ(j.erase("null"), 1u);
|
||||
EXPECT_EQ(j.find("null"), j.end());
|
||||
EXPECT_EQ(j.erase("null"), 0u);
|
||||
|
||||
EXPECT_NE(j.find("string"), j.end());
|
||||
EXPECT_EQ(j.erase("string"), 1u);
|
||||
EXPECT_EQ(j.find("string"), j.end());
|
||||
EXPECT_EQ(j.erase("string"), 0u);
|
||||
|
||||
EXPECT_NE(j.find("floating"), j.end());
|
||||
EXPECT_EQ(j.erase("floating"), 1u);
|
||||
EXPECT_EQ(j.find("floating"), j.end());
|
||||
EXPECT_EQ(j.erase("floating"), 0u);
|
||||
|
||||
EXPECT_NE(j.find("object"), j.end());
|
||||
EXPECT_EQ(j.erase("object"), 1u);
|
||||
EXPECT_EQ(j.find("object"), j.end());
|
||||
EXPECT_EQ(j.erase("object"), 0u);
|
||||
|
||||
EXPECT_NE(j.find("array"), j.end());
|
||||
EXPECT_EQ(j.erase("array"), 1u);
|
||||
EXPECT_EQ(j.find("array"), j.end());
|
||||
EXPECT_EQ(j.erase("array"), 0u);
|
||||
}
|
||||
|
||||
// erase(begin())
|
||||
TEST_F(JsonElementObjectRemoveTest, Begin)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
|
||||
jobject.erase(jobject.begin());
|
||||
EXPECT_EQ(jobject, json({{"b", 1}, {"c", 17u}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, BeginConst)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
|
||||
jobject.erase(jobject.cbegin());
|
||||
EXPECT_EQ(jobject, json({{"b", 1}, {"c", 17u}}));
|
||||
}
|
||||
|
||||
// erase(begin(), end())
|
||||
TEST_F(JsonElementObjectRemoveTest, BeginEnd)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
|
||||
#if 0
|
||||
json::iterator it2 = jobject.erase(jobject.begin(), jobject.end());
|
||||
EXPECT_EQ(jobject, json::object());
|
||||
EXPECT_EQ(it2, jobject.end());
|
||||
#else
|
||||
EXPECT_THROW(jobject.erase(jobject.begin(), jobject.end()), json::type_error);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, BeginEndConst)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
|
||||
#if 0
|
||||
json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cend());
|
||||
EXPECT_EQ(jobject, json::object());
|
||||
EXPECT_EQ(it2, jobject.cend());
|
||||
#else
|
||||
EXPECT_THROW(jobject.erase(jobject.cbegin(), jobject.cend()), json::type_error);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, BeginBegin)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
|
||||
#if 0
|
||||
json::iterator it2 = jobject.erase(jobject.begin(), jobject.begin());
|
||||
EXPECT_EQ(jobject, json({{"a", "a"}, {"b", 1}, {"c", 17u}}));
|
||||
EXPECT_EQ(*it2, json("a"));
|
||||
#else
|
||||
EXPECT_THROW(jobject.erase(jobject.begin(), jobject.end()), json::type_error);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, BeginBeginConst)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
|
||||
#if 0
|
||||
json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cbegin());
|
||||
EXPECT_EQ(jobject, json({{"a", "a"}, {"b", 1}, {"c", 17u}}));
|
||||
EXPECT_EQ(*it2, json("a"));
|
||||
#else
|
||||
EXPECT_THROW(jobject.erase(jobject.cbegin(), jobject.cbegin()), json::type_error);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, Offset)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
|
||||
json::iterator it = jobject.find("b");
|
||||
jobject.erase(it);
|
||||
EXPECT_EQ(jobject, json({{"a", "a"}, {"c", 17u}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, OffsetConst)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}};
|
||||
json::const_iterator it = jobject.find("b");
|
||||
jobject.erase(it);
|
||||
EXPECT_EQ(jobject, json({{"a", "a"}, {"c", 17u}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, Subrange)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
|
||||
#if 0
|
||||
json::iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e"));
|
||||
EXPECT_EQ(jobject, json({{"a", "a"}, {"e", true}}));
|
||||
EXPECT_EQ(*it2, json(true));
|
||||
#else
|
||||
EXPECT_THROW(jobject.erase(jobject.find("b"), jobject.find("e")), json::type_error);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, SubrangeConst)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
|
||||
#if 0
|
||||
json::const_iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e"));
|
||||
EXPECT_EQ(jobject, json({{"a", "a"}, {"e", true}}));
|
||||
EXPECT_EQ(*it2, json(true));
|
||||
#else
|
||||
EXPECT_THROW(jobject.erase(jobject.find("b"), jobject.find("e")), json::type_error);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, Different)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
|
||||
json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
|
||||
EXPECT_THROW_MSG(jobject.erase(jobject2.begin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.202] iterator does not fit current value");
|
||||
EXPECT_THROW_MSG(jobject.erase(jobject.begin(), jobject2.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
EXPECT_THROW_MSG(jobject.erase(jobject2.begin(), jobject.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
EXPECT_THROW_MSG(jobject.erase(jobject2.begin(), jobject2.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectRemoveTest, DifferentConst)
|
||||
{
|
||||
json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}};
|
||||
json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}};
|
||||
EXPECT_THROW_MSG(jobject.erase(jobject2.cbegin()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.202] iterator does not fit current value");
|
||||
EXPECT_THROW_MSG(jobject.erase(jobject.cbegin(), jobject2.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
EXPECT_THROW_MSG(jobject.erase(jobject2.cbegin(), jobject.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
EXPECT_THROW_MSG(jobject.erase(jobject2.cbegin(), jobject2.cend()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.203] iterators do not fit current value");
|
||||
}
|
||||
|
||||
// remove element by key in non-object type
|
||||
TEST(JsonElementNonObjectKeyRemoveTest, Null)
|
||||
{
|
||||
json j_nonobject(json::value_t::null);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase("foo"), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with null");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyRemoveTest, Boolean)
|
||||
{
|
||||
json j_nonobject(json::value_t::boolean);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase("foo"), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with boolean");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyRemoveTest, String)
|
||||
{
|
||||
json j_nonobject(json::value_t::string);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase("foo"), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with string");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyRemoveTest, Array)
|
||||
{
|
||||
json j_nonobject(json::value_t::array);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase("foo"), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with array");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyRemoveTest, Integer)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_integer);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase("foo"), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with number");
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectKeyRemoveTest, Float)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_float);
|
||||
EXPECT_THROW_MSG(j_nonobject.erase("foo"), json::type_error,
|
||||
"[json.exception.type_error.307] cannot use erase() with number");
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectAccessTest, FindExist)
|
||||
{
|
||||
for (auto key :
|
||||
{"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
|
||||
})
|
||||
{
|
||||
EXPECT_NE(j.find(key), j.end());
|
||||
EXPECT_EQ(*j.find(key), j.at(key));
|
||||
EXPECT_NE(j_const.find(key), j_const.end());
|
||||
EXPECT_EQ(*j_const.find(key), j_const.at(key));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectAccessTest, FindNotExist)
|
||||
{
|
||||
EXPECT_EQ(j.find("foo"), j.end());
|
||||
EXPECT_EQ(j_const.find("foo"), j_const.end());
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectFindAccessTest, Null)
|
||||
{
|
||||
json j_nonarray(json::value_t::null);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_EQ(j_nonarray.find("foo"), j_nonarray.end());
|
||||
EXPECT_EQ(j_nonarray_const.find("foo"), j_nonarray_const.end());
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectFindAccessTest, String)
|
||||
{
|
||||
json j_nonarray(json::value_t::string);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_EQ(j_nonarray.find("foo"), j_nonarray.end());
|
||||
EXPECT_EQ(j_nonarray_const.find("foo"), j_nonarray_const.end());
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectFindAccessTest, Object)
|
||||
{
|
||||
json j_nonarray(json::value_t::object);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_EQ(j_nonarray.find("foo"), j_nonarray.end());
|
||||
EXPECT_EQ(j_nonarray_const.find("foo"), j_nonarray_const.end());
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectFindAccessTest, Array)
|
||||
{
|
||||
json j_nonarray(json::value_t::array);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_EQ(j_nonarray.find("foo"), j_nonarray.end());
|
||||
EXPECT_EQ(j_nonarray_const.find("foo"), j_nonarray_const.end());
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectFindAccessTest, Boolean)
|
||||
{
|
||||
json j_nonarray(json::value_t::boolean);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_EQ(j_nonarray.find("foo"), j_nonarray.end());
|
||||
EXPECT_EQ(j_nonarray_const.find("foo"), j_nonarray_const.end());
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectFindAccessTest, Integer)
|
||||
{
|
||||
json j_nonarray(json::value_t::number_integer);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_EQ(j_nonarray.find("foo"), j_nonarray.end());
|
||||
EXPECT_EQ(j_nonarray_const.find("foo"), j_nonarray_const.end());
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectFindAccessTest, Unsigned)
|
||||
{
|
||||
json j_nonarray(json::value_t::number_unsigned);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_EQ(j_nonarray.find("foo"), j_nonarray.end());
|
||||
EXPECT_EQ(j_nonarray_const.find("foo"), j_nonarray_const.end());
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectFindAccessTest, Float)
|
||||
{
|
||||
json j_nonarray(json::value_t::number_float);
|
||||
const json j_nonarray_const(j_nonarray);
|
||||
EXPECT_EQ(j_nonarray.find("foo"), j_nonarray.end());
|
||||
EXPECT_EQ(j_nonarray_const.find("foo"), j_nonarray_const.end());
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectAccessTest, CountExist)
|
||||
{
|
||||
for (auto key :
|
||||
{"integer", "unsigned", "floating", "null", "string", "boolean", "object", "array"
|
||||
})
|
||||
{
|
||||
EXPECT_EQ(j.count(key), 1u);
|
||||
EXPECT_EQ(j_const.count(key), 1u);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectAccessTest, CountNotExist)
|
||||
{
|
||||
EXPECT_EQ(j.count("foo"), 0u);
|
||||
EXPECT_EQ(j_const.count("foo"), 0u);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectCountAccessTest, Null)
|
||||
{
|
||||
json j_nonobject(json::value_t::null);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_EQ(j_nonobject.count("foo"), 0u);
|
||||
EXPECT_EQ(j_nonobject_const.count("foo"), 0u);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectCountAccessTest, String)
|
||||
{
|
||||
json j_nonobject(json::value_t::string);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_EQ(j_nonobject.count("foo"), 0u);
|
||||
EXPECT_EQ(j_nonobject_const.count("foo"), 0u);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectCountAccessTest, Object)
|
||||
{
|
||||
json j_nonobject(json::value_t::object);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_EQ(j_nonobject.count("foo"), 0u);
|
||||
EXPECT_EQ(j_nonobject_const.count("foo"), 0u);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectCountAccessTest, Array)
|
||||
{
|
||||
json j_nonobject(json::value_t::array);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_EQ(j_nonobject.count("foo"), 0u);
|
||||
EXPECT_EQ(j_nonobject_const.count("foo"), 0u);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectCountAccessTest, Boolean)
|
||||
{
|
||||
json j_nonobject(json::value_t::boolean);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_EQ(j_nonobject.count("foo"), 0u);
|
||||
EXPECT_EQ(j_nonobject_const.count("foo"), 0u);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectCountAccessTest, Integer)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_integer);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_EQ(j_nonobject.count("foo"), 0u);
|
||||
EXPECT_EQ(j_nonobject_const.count("foo"), 0u);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectCountAccessTest, Unsigned)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_unsigned);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_EQ(j_nonobject.count("foo"), 0u);
|
||||
EXPECT_EQ(j_nonobject_const.count("foo"), 0u);
|
||||
}
|
||||
|
||||
TEST(JsonElementNonObjectCountAccessTest, Float)
|
||||
{
|
||||
json j_nonobject(json::value_t::number_float);
|
||||
const json j_nonobject_const(j_nonobject);
|
||||
EXPECT_EQ(j_nonobject.count("foo"), 0u);
|
||||
EXPECT_EQ(j_nonobject_const.count("foo"), 0u);
|
||||
}
|
||||
|
||||
TEST_F(JsonElementObjectAccessTest, PointerValueNotExist)
|
||||
{
|
||||
EXPECT_EQ(j.value("/not/existing"_json_pointer, 2), 2);
|
||||
EXPECT_EQ(j.value("/not/existing"_json_pointer, 2u), 2u);
|
||||
EXPECT_EQ(j.value("/not/existing"_json_pointer, false), false);
|
||||
EXPECT_EQ(j.value("/not/existing"_json_pointer, "bar"), "bar");
|
||||
EXPECT_LT(std::fabs(j.value("/not/existing"_json_pointer, 12.34) - 12.34), 0.001);
|
||||
EXPECT_EQ(j.value("/not/existing"_json_pointer, json({{"foo", "bar"}})), json({{"foo", "bar"}}));
|
||||
EXPECT_EQ(j.value("/not/existing"_json_pointer, json({10, 100})), json({10, 100}));
|
||||
|
||||
EXPECT_EQ(j_const.value("/not/existing"_json_pointer, 2), 2);
|
||||
EXPECT_EQ(j_const.value("/not/existing"_json_pointer, 2u), 2u);
|
||||
EXPECT_EQ(j_const.value("/not/existing"_json_pointer, false), false);
|
||||
EXPECT_EQ(j_const.value("/not/existing"_json_pointer, "bar"), "bar");
|
||||
EXPECT_LT(std::fabs(j_const.value("/not/existing"_json_pointer, 12.34) - 12.34), 0.001);
|
||||
EXPECT_EQ(j_const.value("/not/existing"_json_pointer, json({{"foo", "bar"}})), json({{"foo", "bar"}}));
|
||||
EXPECT_EQ(j_const.value("/not/existing"_json_pointer, json({10, 100})), json({10, 100}));
|
||||
}
|
||||
385
wpiutil/src/test/native/cpp/json/unit-inspection.cpp
Normal file
385
wpiutil/src/test/native/cpp/json/unit-inspection.cpp
Normal file
@@ -0,0 +1,385 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
TEST(JsonConvTypeCheckTest, Object)
|
||||
{
|
||||
json j {{"foo", 1}, {"bar", false}};
|
||||
EXPECT_FALSE(j.is_null());
|
||||
EXPECT_FALSE(j.is_boolean());
|
||||
EXPECT_FALSE(j.is_number());
|
||||
EXPECT_FALSE(j.is_number_integer());
|
||||
EXPECT_FALSE(j.is_number_unsigned());
|
||||
EXPECT_FALSE(j.is_number_float());
|
||||
EXPECT_TRUE(j.is_object());
|
||||
EXPECT_FALSE(j.is_array());
|
||||
EXPECT_FALSE(j.is_string());
|
||||
EXPECT_FALSE(j.is_discarded());
|
||||
EXPECT_FALSE(j.is_primitive());
|
||||
EXPECT_TRUE(j.is_structured());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeCheckTest, Array)
|
||||
{
|
||||
json j {"foo", 1, 1u, 42.23, false};
|
||||
EXPECT_FALSE(j.is_null());
|
||||
EXPECT_FALSE(j.is_boolean());
|
||||
EXPECT_FALSE(j.is_number());
|
||||
EXPECT_FALSE(j.is_number_integer());
|
||||
EXPECT_FALSE(j.is_number_unsigned());
|
||||
EXPECT_FALSE(j.is_number_float());
|
||||
EXPECT_FALSE(j.is_object());
|
||||
EXPECT_TRUE(j.is_array());
|
||||
EXPECT_FALSE(j.is_string());
|
||||
EXPECT_FALSE(j.is_discarded());
|
||||
EXPECT_FALSE(j.is_primitive());
|
||||
EXPECT_TRUE(j.is_structured());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeCheckTest, Null)
|
||||
{
|
||||
json j(nullptr);
|
||||
EXPECT_TRUE(j.is_null());
|
||||
EXPECT_FALSE(j.is_boolean());
|
||||
EXPECT_FALSE(j.is_number());
|
||||
EXPECT_FALSE(j.is_number_integer());
|
||||
EXPECT_FALSE(j.is_number_unsigned());
|
||||
EXPECT_FALSE(j.is_number_float());
|
||||
EXPECT_FALSE(j.is_object());
|
||||
EXPECT_FALSE(j.is_array());
|
||||
EXPECT_FALSE(j.is_string());
|
||||
EXPECT_FALSE(j.is_discarded());
|
||||
EXPECT_TRUE(j.is_primitive());
|
||||
EXPECT_FALSE(j.is_structured());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeCheckTest, Boolean)
|
||||
{
|
||||
json j(true);
|
||||
EXPECT_FALSE(j.is_null());
|
||||
EXPECT_TRUE(j.is_boolean());
|
||||
EXPECT_FALSE(j.is_number());
|
||||
EXPECT_FALSE(j.is_number_integer());
|
||||
EXPECT_FALSE(j.is_number_unsigned());
|
||||
EXPECT_FALSE(j.is_number_float());
|
||||
EXPECT_FALSE(j.is_object());
|
||||
EXPECT_FALSE(j.is_array());
|
||||
EXPECT_FALSE(j.is_string());
|
||||
EXPECT_FALSE(j.is_discarded());
|
||||
EXPECT_TRUE(j.is_primitive());
|
||||
EXPECT_FALSE(j.is_structured());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeCheckTest, String)
|
||||
{
|
||||
json j("Hello world");
|
||||
EXPECT_FALSE(j.is_null());
|
||||
EXPECT_FALSE(j.is_boolean());
|
||||
EXPECT_FALSE(j.is_number());
|
||||
EXPECT_FALSE(j.is_number_integer());
|
||||
EXPECT_FALSE(j.is_number_unsigned());
|
||||
EXPECT_FALSE(j.is_number_float());
|
||||
EXPECT_FALSE(j.is_object());
|
||||
EXPECT_FALSE(j.is_array());
|
||||
EXPECT_TRUE(j.is_string());
|
||||
EXPECT_FALSE(j.is_discarded());
|
||||
EXPECT_TRUE(j.is_primitive());
|
||||
EXPECT_FALSE(j.is_structured());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeCheckTest, Integer)
|
||||
{
|
||||
json j(42);
|
||||
EXPECT_FALSE(j.is_null());
|
||||
EXPECT_FALSE(j.is_boolean());
|
||||
EXPECT_TRUE(j.is_number());
|
||||
EXPECT_TRUE(j.is_number_integer());
|
||||
EXPECT_FALSE(j.is_number_unsigned());
|
||||
EXPECT_FALSE(j.is_number_float());
|
||||
EXPECT_FALSE(j.is_object());
|
||||
EXPECT_FALSE(j.is_array());
|
||||
EXPECT_FALSE(j.is_string());
|
||||
EXPECT_FALSE(j.is_discarded());
|
||||
EXPECT_TRUE(j.is_primitive());
|
||||
EXPECT_FALSE(j.is_structured());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeCheckTest, Unsigned)
|
||||
{
|
||||
json j(42u);
|
||||
EXPECT_FALSE(j.is_null());
|
||||
EXPECT_FALSE(j.is_boolean());
|
||||
EXPECT_TRUE(j.is_number());
|
||||
EXPECT_TRUE(j.is_number_integer());
|
||||
EXPECT_TRUE(j.is_number_unsigned());
|
||||
EXPECT_FALSE(j.is_number_float());
|
||||
EXPECT_FALSE(j.is_object());
|
||||
EXPECT_FALSE(j.is_array());
|
||||
EXPECT_FALSE(j.is_string());
|
||||
EXPECT_FALSE(j.is_discarded());
|
||||
EXPECT_TRUE(j.is_primitive());
|
||||
EXPECT_FALSE(j.is_structured());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeCheckTest, Float)
|
||||
{
|
||||
json j(42.23);
|
||||
EXPECT_FALSE(j.is_null());
|
||||
EXPECT_FALSE(j.is_boolean());
|
||||
EXPECT_TRUE(j.is_number());
|
||||
EXPECT_FALSE(j.is_number_integer());
|
||||
EXPECT_FALSE(j.is_number_unsigned());
|
||||
EXPECT_TRUE(j.is_number_float());
|
||||
EXPECT_FALSE(j.is_object());
|
||||
EXPECT_FALSE(j.is_array());
|
||||
EXPECT_FALSE(j.is_string());
|
||||
EXPECT_FALSE(j.is_discarded());
|
||||
EXPECT_TRUE(j.is_primitive());
|
||||
EXPECT_FALSE(j.is_structured());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeCheckTest, Discarded)
|
||||
{
|
||||
json j(json::value_t::discarded);
|
||||
EXPECT_FALSE(j.is_null());
|
||||
EXPECT_FALSE(j.is_boolean());
|
||||
EXPECT_FALSE(j.is_number());
|
||||
EXPECT_FALSE(j.is_number_integer());
|
||||
EXPECT_FALSE(j.is_number_unsigned());
|
||||
EXPECT_FALSE(j.is_number_float());
|
||||
EXPECT_FALSE(j.is_object());
|
||||
EXPECT_FALSE(j.is_array());
|
||||
EXPECT_FALSE(j.is_string());
|
||||
EXPECT_TRUE(j.is_discarded());
|
||||
EXPECT_FALSE(j.is_primitive());
|
||||
EXPECT_FALSE(j.is_structured());
|
||||
}
|
||||
|
||||
class JsonConvSerializationTest : public ::testing::Test {
|
||||
protected:
|
||||
json j {{"object", json::object()}, {"array", {1, 2, 3, 4}}, {"number", 42}, {"boolean", false}, {"null", nullptr}, {"string", "Hello world"} };
|
||||
};
|
||||
#if 0
|
||||
// no indent / indent=-1
|
||||
TEST_F(JsonConvSerializationTest, NoIndent)
|
||||
{
|
||||
EXPECT_EQ(j.dump(),
|
||||
"{\"array\":[1,2,3,4],\"boolean\":false,\"null\":null,\"number\":42,\"object\":{},\"string\":\"Hello world\"}");
|
||||
|
||||
EXPECT_EQ(j.dump(), j.dump(-1));
|
||||
}
|
||||
|
||||
// indent=0
|
||||
TEST_F(JsonConvSerializationTest, Indent0)
|
||||
{
|
||||
EXPECT_EQ(j.dump(0),
|
||||
"{\n\"array\": [\n1,\n2,\n3,\n4\n],\n\"boolean\": false,\n\"null\": null,\n\"number\": 42,\n\"object\": {},\n\"string\": \"Hello world\"\n}");
|
||||
}
|
||||
|
||||
// indent=1, space='\t'
|
||||
TEST_F(JsonConvSerializationTest, Indent1)
|
||||
{
|
||||
EXPECT_EQ(j.dump(1, '\t'),
|
||||
"{\n\t\"array\": [\n\t\t1,\n\t\t2,\n\t\t3,\n\t\t4\n\t],\n\t\"boolean\": false,\n\t\"null\": null,\n\t\"number\": 42,\n\t\"object\": {},\n\t\"string\": \"Hello world\"\n}");
|
||||
}
|
||||
|
||||
// indent=4
|
||||
TEST_F(JsonConvSerializationTest, Indent4)
|
||||
{
|
||||
EXPECT_EQ(j.dump(4),
|
||||
"{\n \"array\": [\n 1,\n 2,\n 3,\n 4\n ],\n \"boolean\": false,\n \"null\": null,\n \"number\": 42,\n \"object\": {},\n \"string\": \"Hello world\"\n}");
|
||||
}
|
||||
#endif
|
||||
// indent=x
|
||||
TEST_F(JsonConvSerializationTest, IndentX)
|
||||
{
|
||||
EXPECT_EQ(j.dump().size(), 94u);
|
||||
EXPECT_EQ(j.dump(1).size(), 127u);
|
||||
EXPECT_EQ(j.dump(2).size(), 142u);
|
||||
EXPECT_EQ(j.dump(512).size(), 7792u);
|
||||
}
|
||||
|
||||
// dump and floating-point numbers
|
||||
TEST_F(JsonConvSerializationTest, Float)
|
||||
{
|
||||
auto s = json(42.23).dump();
|
||||
EXPECT_NE(s.find("42.23"), std::string::npos);
|
||||
}
|
||||
|
||||
// dump and small floating-point numbers
|
||||
TEST_F(JsonConvSerializationTest, SmallFloat)
|
||||
{
|
||||
auto s = json(1.23456e-78).dump();
|
||||
EXPECT_NE(s.find("1.23456e-78"), std::string::npos);
|
||||
}
|
||||
|
||||
// dump and non-ASCII characters
|
||||
TEST_F(JsonConvSerializationTest, NonAscii)
|
||||
{
|
||||
EXPECT_EQ(json("ä").dump(), "\"ä\"");
|
||||
EXPECT_EQ(json("Ö").dump(), "\"Ö\"");
|
||||
EXPECT_EQ(json("❤️").dump(), "\"❤️\"");
|
||||
}
|
||||
|
||||
// serialization of discarded element
|
||||
TEST_F(JsonConvSerializationTest, Discarded)
|
||||
{
|
||||
json j_discarded(json::value_t::discarded);
|
||||
EXPECT_EQ(j_discarded.dump(), "<discarded>");
|
||||
}
|
||||
|
||||
TEST(JsonConvRoundTripTest, Case)
|
||||
{
|
||||
for (const auto& s :
|
||||
{"3.141592653589793", "1000000000000000010E5"
|
||||
})
|
||||
{
|
||||
SCOPED_TRACE(s);
|
||||
json j1 = json::parse(s);
|
||||
std::string s1 = j1.dump();
|
||||
json j2 = json::parse(s1);
|
||||
std::string s2 = j2.dump();
|
||||
EXPECT_EQ(s1, s2);
|
||||
}
|
||||
}
|
||||
|
||||
// return the type of the object (explicit)
|
||||
TEST(JsonConvTypeExplicitTest, Null)
|
||||
{
|
||||
json j = nullptr;
|
||||
EXPECT_EQ(j.type(), json::value_t::null);
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeExplicitTest, Object)
|
||||
{
|
||||
json j = {{"foo", "bar"}};
|
||||
EXPECT_EQ(j.type(), json::value_t::object);
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeExplicitTest, Array)
|
||||
{
|
||||
json j = {1, 2, 3, 4};
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeExplicitTest, Boolean)
|
||||
{
|
||||
json j = true;
|
||||
EXPECT_EQ(j.type(), json::value_t::boolean);
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeExplicitTest, String)
|
||||
{
|
||||
json j = "Hello world";
|
||||
EXPECT_EQ(j.type(), json::value_t::string);
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeExplicitTest, Integer)
|
||||
{
|
||||
json j = 23;
|
||||
EXPECT_EQ(j.type(), json::value_t::number_integer);
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeExplicitTest, Unsigned)
|
||||
{
|
||||
json j = 23u;
|
||||
EXPECT_EQ(j.type(), json::value_t::number_unsigned);
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeExplicitTest, Float)
|
||||
{
|
||||
json j = 42.23;
|
||||
EXPECT_EQ(j.type(), json::value_t::number_float);
|
||||
}
|
||||
|
||||
// return the type of the object (implicit)
|
||||
TEST(JsonConvTypeImplicitTest, Null)
|
||||
{
|
||||
json j = nullptr;
|
||||
json::value_t t = j;
|
||||
EXPECT_EQ(t, j.type());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeImplicitTest, Object)
|
||||
{
|
||||
json j = {{"foo", "bar"}};
|
||||
json::value_t t = j;
|
||||
EXPECT_EQ(t, j.type());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeImplicitTest, Array)
|
||||
{
|
||||
json j = {1, 2, 3, 4};
|
||||
json::value_t t = j;
|
||||
EXPECT_EQ(t, j.type());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeImplicitTest, Boolean)
|
||||
{
|
||||
json j = true;
|
||||
json::value_t t = j;
|
||||
EXPECT_EQ(t, j.type());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeImplicitTest, String)
|
||||
{
|
||||
json j = "Hello world";
|
||||
json::value_t t = j;
|
||||
EXPECT_EQ(t, j.type());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeImplicitTest, Integer)
|
||||
{
|
||||
json j = 23;
|
||||
json::value_t t = j;
|
||||
EXPECT_EQ(t, j.type());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeImplicitTest, Unsigned)
|
||||
{
|
||||
json j = 23u;
|
||||
json::value_t t = j;
|
||||
EXPECT_EQ(t, j.type());
|
||||
}
|
||||
|
||||
TEST(JsonConvTypeImplicitTest, Float)
|
||||
{
|
||||
json j = 42.23;
|
||||
json::value_t t = j;
|
||||
EXPECT_EQ(t, j.type());
|
||||
}
|
||||
745
wpiutil/src/test/native/cpp/json/unit-iterator_wrapper.cpp
Normal file
745
wpiutil/src/test/native/cpp/json/unit-iterator_wrapper.cpp
Normal file
@@ -0,0 +1,745 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
class JsonIteratorWrapperObjectTest : public ::testing::Test {
|
||||
protected:
|
||||
json j = {{"A", 1}, {"B", 2}};
|
||||
};
|
||||
|
||||
TEST_F(JsonIteratorWrapperObjectTest, Value)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "A");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "B");
|
||||
EXPECT_EQ(i.value(), json(2));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperObjectTest, Reference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "A");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
|
||||
// change the value
|
||||
i.value() = json(11);
|
||||
EXPECT_EQ(i.value(), json(11));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "B");
|
||||
EXPECT_EQ(i.value(), json(2));
|
||||
|
||||
// change the value
|
||||
i.value() = json(22);
|
||||
EXPECT_EQ(i.value(), json(22));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
|
||||
// check if values where changed
|
||||
EXPECT_EQ(j, json({{"A", 11}, {"B", 22}}));
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperObjectTest, ConstValue)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "A");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "B");
|
||||
EXPECT_EQ(i.value(), json(2));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperObjectTest, ConstReference)
|
||||
{
|
||||
json j = {{"A", 1}, {"B", 2}};
|
||||
int counter = 1;
|
||||
|
||||
for (const auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "A");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "B");
|
||||
EXPECT_EQ(i.value(), json(2));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
class JsonIteratorWrapperConstObjectTest : public ::testing::Test {
|
||||
protected:
|
||||
const json j = {{"A", 1}, {"B", 2}};
|
||||
};
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstObjectTest, Value)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "A");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "B");
|
||||
EXPECT_EQ(i.value(), json(2));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstObjectTest, Reference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "A");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "B");
|
||||
EXPECT_EQ(i.value(), json(2));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstObjectTest, ConstValue)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "A");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "B");
|
||||
EXPECT_EQ(i.value(), json(2));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstObjectTest, ConstReference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "A");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "B");
|
||||
EXPECT_EQ(i.value(), json(2));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
class JsonIteratorWrapperArrayTest : public ::testing::Test {
|
||||
protected:
|
||||
json j = {"A", "B"};
|
||||
};
|
||||
|
||||
TEST_F(JsonIteratorWrapperArrayTest, Value)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "0");
|
||||
EXPECT_EQ(i.value(), "A");
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "1");
|
||||
EXPECT_EQ(i.value(), "B");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperArrayTest, Reference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "0");
|
||||
EXPECT_EQ(i.value(), "A");
|
||||
|
||||
// change the value
|
||||
i.value() = "AA";
|
||||
EXPECT_EQ(i.value(), "AA");
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "1");
|
||||
EXPECT_EQ(i.value(), "B");
|
||||
|
||||
// change the value
|
||||
i.value() = "BB";
|
||||
EXPECT_EQ(i.value(), "BB");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
|
||||
// check if values where changed
|
||||
EXPECT_EQ(j, json({"AA", "BB"}));
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperArrayTest, ConstValue)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "0");
|
||||
EXPECT_EQ(i.value(), "A");
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "1");
|
||||
EXPECT_EQ(i.value(), "B");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperArrayTest, ConstReference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "0");
|
||||
EXPECT_EQ(i.value(), "A");
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "1");
|
||||
EXPECT_EQ(i.value(), "B");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
class JsonIteratorWrapperConstArrayTest : public ::testing::Test {
|
||||
protected:
|
||||
const json j = {"A", "B"};
|
||||
};
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstArrayTest, Value)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "0");
|
||||
EXPECT_EQ(i.value(), "A");
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "1");
|
||||
EXPECT_EQ(i.value(), "B");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstArrayTest, Reference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "0");
|
||||
EXPECT_EQ(i.value(), "A");
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "1");
|
||||
EXPECT_EQ(i.value(), "B");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstArrayTest, ConstValue)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "0");
|
||||
EXPECT_EQ(i.value(), "A");
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "1");
|
||||
EXPECT_EQ(i.value(), "B");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstArrayTest, ConstReference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
switch (counter++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "0");
|
||||
EXPECT_EQ(i.value(), "A");
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
EXPECT_EQ(i.key(), "1");
|
||||
EXPECT_EQ(i.value(), "B");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 3);
|
||||
}
|
||||
|
||||
class JsonIteratorWrapperPrimitiveTest : public ::testing::Test {
|
||||
protected:
|
||||
json j = 1;
|
||||
};
|
||||
|
||||
TEST_F(JsonIteratorWrapperPrimitiveTest, Value)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
++counter;
|
||||
EXPECT_EQ(i.key(), "");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 2);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperPrimitiveTest, Reference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
++counter;
|
||||
EXPECT_EQ(i.key(), "");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
|
||||
// change value
|
||||
i.value() = json(2);
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 2);
|
||||
|
||||
// check if value has changed
|
||||
EXPECT_EQ(j, json(2));
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperPrimitiveTest, ConstValue)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
++counter;
|
||||
EXPECT_EQ(i.key(), "");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 2);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperPrimitiveTest, ConstReference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
++counter;
|
||||
EXPECT_EQ(i.key(), "");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 2);
|
||||
}
|
||||
|
||||
class JsonIteratorWrapperConstPrimitiveTest : public ::testing::Test {
|
||||
protected:
|
||||
const json j = 1;
|
||||
};
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstPrimitiveTest, Value)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
++counter;
|
||||
EXPECT_EQ(i.key(), "");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 2);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstPrimitiveTest, Reference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
++counter;
|
||||
EXPECT_EQ(i.key(), "");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 2);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstPrimitiveTest, ConstValue)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
++counter;
|
||||
EXPECT_EQ(i.key(), "");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 2);
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorWrapperConstPrimitiveTest, ConstReference)
|
||||
{
|
||||
int counter = 1;
|
||||
|
||||
for (const auto& i : json::iterator_wrapper(j))
|
||||
{
|
||||
SCOPED_TRACE(counter);
|
||||
++counter;
|
||||
EXPECT_EQ(i.key(), "");
|
||||
EXPECT_EQ(i.value(), json(1));
|
||||
}
|
||||
|
||||
EXPECT_EQ(counter, 2);
|
||||
}
|
||||
1616
wpiutil/src/test/native/cpp/json/unit-iterators1.cpp
Normal file
1616
wpiutil/src/test/native/cpp/json/unit-iterators1.cpp
Normal file
File diff suppressed because it is too large
Load Diff
899
wpiutil/src/test/native/cpp/json/unit-iterators2.cpp
Normal file
899
wpiutil/src/test/native/cpp/json/unit-iterators2.cpp
Normal file
@@ -0,0 +1,899 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
TEST(JsonIteratorTest, Comparisons)
|
||||
{
|
||||
json j_values = {nullptr, true, 42, 42u, 23.23, {{"one", 1}, {"two", 2}}, {1, 2, 3, 4, 5}, "Hello, world"};
|
||||
|
||||
for (json& j : j_values)
|
||||
{
|
||||
SCOPED_TRACE(j.dump());
|
||||
auto it1 = j.begin();
|
||||
auto it2 = j.begin();
|
||||
auto it3 = j.begin();
|
||||
++it2;
|
||||
++it3;
|
||||
++it3;
|
||||
auto it1_c = j.cbegin();
|
||||
auto it2_c = j.cbegin();
|
||||
auto it3_c = j.cbegin();
|
||||
++it2_c;
|
||||
++it3_c;
|
||||
++it3_c;
|
||||
|
||||
// comparison: equal
|
||||
{
|
||||
EXPECT_TRUE(it1 == it1);
|
||||
EXPECT_FALSE(it1 == it2);
|
||||
EXPECT_FALSE(it1 == it3);
|
||||
EXPECT_FALSE(it2 == it3);
|
||||
EXPECT_TRUE(it1_c == it1_c);
|
||||
EXPECT_FALSE(it1_c == it2_c);
|
||||
EXPECT_FALSE(it1_c == it3_c);
|
||||
EXPECT_FALSE(it2_c == it3_c);
|
||||
}
|
||||
|
||||
// comparison: not equal
|
||||
{
|
||||
// check definition
|
||||
EXPECT_EQ( (it1 != it1), !(it1 == it1) );
|
||||
EXPECT_EQ( (it1 != it2), !(it1 == it2) );
|
||||
EXPECT_EQ( (it1 != it3), !(it1 == it3) );
|
||||
EXPECT_EQ( (it2 != it3), !(it2 == it3) );
|
||||
EXPECT_EQ( (it1_c != it1_c), !(it1_c == it1_c) );
|
||||
EXPECT_EQ( (it1_c != it2_c), !(it1_c == it2_c) );
|
||||
EXPECT_EQ( (it1_c != it3_c), !(it1_c == it3_c) );
|
||||
EXPECT_EQ( (it2_c != it3_c), !(it2_c == it3_c) );
|
||||
}
|
||||
|
||||
// comparison: smaller
|
||||
{
|
||||
if (j.type() == json::value_t::object)
|
||||
{
|
||||
EXPECT_THROW_MSG(it1 < it1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 < it2, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2 < it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 < it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c < it1_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c < it2_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2_c < it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c < it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_FALSE(it1 < it1);
|
||||
EXPECT_TRUE(it1 < it2);
|
||||
EXPECT_TRUE(it1 < it3);
|
||||
EXPECT_TRUE(it2 < it3);
|
||||
EXPECT_FALSE(it1_c < it1_c);
|
||||
EXPECT_TRUE(it1_c < it2_c);
|
||||
EXPECT_TRUE(it1_c < it3_c);
|
||||
EXPECT_TRUE(it2_c < it3_c);
|
||||
}
|
||||
}
|
||||
|
||||
// comparison: less than or equal
|
||||
{
|
||||
if (j.type() == json::value_t::object)
|
||||
{
|
||||
EXPECT_THROW_MSG(it1 <= it1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 <= it2, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2 <= it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 <= it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c <= it1_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c <= it2_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2_c <= it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c <= it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
}
|
||||
else
|
||||
{
|
||||
// check definition
|
||||
EXPECT_EQ( (it1 <= it1), !(it1 < it1) );
|
||||
EXPECT_EQ( (it1 <= it2), !(it2 < it1) );
|
||||
EXPECT_EQ( (it1 <= it3), !(it3 < it1) );
|
||||
EXPECT_EQ( (it2 <= it3), !(it3 < it2) );
|
||||
EXPECT_EQ( (it1_c <= it1_c), !(it1_c < it1_c) );
|
||||
EXPECT_EQ( (it1_c <= it2_c), !(it2_c < it1_c) );
|
||||
EXPECT_EQ( (it1_c <= it3_c), !(it3_c < it1_c) );
|
||||
EXPECT_EQ( (it2_c <= it3_c), !(it3_c < it2_c) );
|
||||
}
|
||||
}
|
||||
|
||||
// comparison: greater than
|
||||
{
|
||||
if (j.type() == json::value_t::object)
|
||||
{
|
||||
EXPECT_THROW_MSG(it1 > it1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 > it2, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2 > it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 > it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c > it1_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c > it2_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2_c > it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c > it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
}
|
||||
else
|
||||
{
|
||||
// check definition
|
||||
EXPECT_EQ( (it1 > it1), (it1 < it1) );
|
||||
EXPECT_EQ( (it1 > it2), (it2 < it1) );
|
||||
EXPECT_EQ( (it1 > it3), (it3 < it1) );
|
||||
EXPECT_EQ( (it2 > it3), (it3 < it2) );
|
||||
EXPECT_EQ( (it1_c > it1_c), (it1_c < it1_c) );
|
||||
EXPECT_EQ( (it1_c > it2_c), (it2_c < it1_c) );
|
||||
EXPECT_EQ( (it1_c > it3_c), (it3_c < it1_c) );
|
||||
EXPECT_EQ( (it2_c > it3_c), (it3_c < it2_c) );
|
||||
}
|
||||
}
|
||||
|
||||
// comparison: greater than or equal
|
||||
{
|
||||
if (j.type() == json::value_t::object)
|
||||
{
|
||||
EXPECT_THROW_MSG(it1 >= it1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 >= it2, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2 >= it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 >= it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c >= it1_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c >= it2_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2_c >= it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c >= it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
}
|
||||
else
|
||||
{
|
||||
// check definition
|
||||
EXPECT_EQ( (it1 >= it1), !(it1 < it1) );
|
||||
EXPECT_EQ( (it1 >= it2), !(it1 < it2) );
|
||||
EXPECT_EQ( (it1 >= it3), !(it1 < it3) );
|
||||
EXPECT_EQ( (it2 >= it3), !(it2 < it3) );
|
||||
EXPECT_EQ( (it1_c >= it1_c), !(it1_c < it1_c) );
|
||||
EXPECT_EQ( (it1_c >= it2_c), !(it1_c < it2_c) );
|
||||
EXPECT_EQ( (it1_c >= it3_c), !(it1_c < it3_c) );
|
||||
EXPECT_EQ( (it2_c >= it3_c), !(it2_c < it3_c) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check exceptions if different objects are compared
|
||||
for (auto j : j_values)
|
||||
{
|
||||
for (auto k : j_values)
|
||||
{
|
||||
if (j != k)
|
||||
{
|
||||
EXPECT_THROW_MSG(j.begin() == k.begin(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
EXPECT_THROW_MSG(j.cbegin() == k.cbegin(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
|
||||
EXPECT_THROW_MSG(j.begin() < k.begin(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
EXPECT_THROW_MSG(j.cbegin() < k.cbegin(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JsonIteratorArithmeticTest : public ::testing::Test {
|
||||
protected:
|
||||
json j_object = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
json j_array = {1, 2, 3, 4, 5, 6};
|
||||
json j_null = nullptr;
|
||||
json j_value = 42;
|
||||
};
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, AddSubObject)
|
||||
{
|
||||
{
|
||||
auto it = j_object.begin();
|
||||
EXPECT_THROW_MSG(it += 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.cbegin();
|
||||
EXPECT_THROW_MSG(it += 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.begin();
|
||||
EXPECT_THROW_MSG(it + 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.cbegin();
|
||||
EXPECT_THROW_MSG(it + 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.begin();
|
||||
EXPECT_THROW_MSG(1 + it, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.cbegin();
|
||||
EXPECT_THROW_MSG(1 + it, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.begin();
|
||||
EXPECT_THROW_MSG(it -= 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.cbegin();
|
||||
EXPECT_THROW_MSG(it -= 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.begin();
|
||||
EXPECT_THROW_MSG(it - 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.cbegin();
|
||||
EXPECT_THROW_MSG(it - 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.begin();
|
||||
EXPECT_THROW_MSG(it - it, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.cbegin();
|
||||
EXPECT_THROW_MSG(it - it, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, AddSubArray)
|
||||
{
|
||||
auto it = j_array.begin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_array.begin() + 3), it);
|
||||
EXPECT_EQ(json::iterator(3 + j_array.begin()), it);
|
||||
EXPECT_EQ((it - 3), j_array.begin());
|
||||
EXPECT_EQ((it - j_array.begin()), 3);
|
||||
EXPECT_EQ(*it, json(4));
|
||||
it -= 2;
|
||||
EXPECT_EQ(*it, json(2));
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, AddSubArrayConst)
|
||||
{
|
||||
auto it = j_array.cbegin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_array.cbegin() + 3), it);
|
||||
EXPECT_EQ(json::const_iterator(3 + j_array.cbegin()), it);
|
||||
EXPECT_EQ((it - 3), j_array.cbegin());
|
||||
EXPECT_EQ((it - j_array.cbegin()), 3);
|
||||
EXPECT_EQ(*it, json(4));
|
||||
it -= 2;
|
||||
EXPECT_EQ(*it, json(2));
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, AddSubNull)
|
||||
{
|
||||
auto it = j_null.begin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_null.begin() + 3), it);
|
||||
EXPECT_EQ(json::iterator(3 + j_null.begin()), it);
|
||||
EXPECT_EQ((it - 3), j_null.begin());
|
||||
EXPECT_EQ((it - j_null.begin()), 3);
|
||||
EXPECT_NE(it, j_null.end());
|
||||
it -= 3;
|
||||
EXPECT_EQ(it, j_null.end());
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, AddSubNullConst)
|
||||
{
|
||||
auto it = j_null.cbegin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_null.cbegin() + 3), it);
|
||||
EXPECT_EQ(json::const_iterator(3 + j_null.cbegin()), it);
|
||||
EXPECT_EQ((it - 3), j_null.cbegin());
|
||||
EXPECT_EQ((it - j_null.cbegin()), 3);
|
||||
EXPECT_NE(it, j_null.cend());
|
||||
it -= 3;
|
||||
EXPECT_EQ(it, j_null.cend());
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, AddSubValue)
|
||||
{
|
||||
auto it = j_value.begin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_value.begin() + 3), it);
|
||||
EXPECT_EQ(json::iterator(3 + j_value.begin()), it);
|
||||
EXPECT_EQ((it - 3), j_value.begin());
|
||||
EXPECT_EQ((it - j_value.begin()), 3);
|
||||
EXPECT_NE(it, j_value.end());
|
||||
it -= 3;
|
||||
EXPECT_EQ(*it, json(42));
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, AddSubValueConst)
|
||||
{
|
||||
auto it = j_value.cbegin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_value.cbegin() + 3), it);
|
||||
EXPECT_EQ(json::const_iterator(3 + j_value.cbegin()), it);
|
||||
EXPECT_EQ((it - 3), j_value.cbegin());
|
||||
EXPECT_EQ((it - j_value.cbegin()), 3);
|
||||
EXPECT_NE(it, j_value.cend());
|
||||
it -= 3;
|
||||
EXPECT_EQ(*it, json(42));
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, SubscriptObject)
|
||||
{
|
||||
auto it = j_object.begin();
|
||||
EXPECT_THROW_MSG(it[0], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, SubscriptObjectConst)
|
||||
{
|
||||
auto it = j_object.cbegin();
|
||||
EXPECT_THROW_MSG(it[0], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.208] cannot use operator[] for object iterators");
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, SubscriptArray)
|
||||
{
|
||||
auto it = j_array.begin();
|
||||
EXPECT_EQ(it[0], json(1));
|
||||
EXPECT_EQ(it[1], json(2));
|
||||
EXPECT_EQ(it[2], json(3));
|
||||
EXPECT_EQ(it[3], json(4));
|
||||
EXPECT_EQ(it[4], json(5));
|
||||
EXPECT_EQ(it[5], json(6));
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, SubscriptArrayConst)
|
||||
{
|
||||
auto it = j_array.cbegin();
|
||||
EXPECT_EQ(it[0], json(1));
|
||||
EXPECT_EQ(it[1], json(2));
|
||||
EXPECT_EQ(it[2], json(3));
|
||||
EXPECT_EQ(it[3], json(4));
|
||||
EXPECT_EQ(it[4], json(5));
|
||||
EXPECT_EQ(it[5], json(6));
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, SubscriptNull)
|
||||
{
|
||||
auto it = j_null.begin();
|
||||
EXPECT_THROW_MSG(it[0], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, SubscriptNullConst)
|
||||
{
|
||||
auto it = j_null.cbegin();
|
||||
EXPECT_THROW_MSG(it[0], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, SubscriptValue)
|
||||
{
|
||||
auto it = j_value.begin();
|
||||
EXPECT_EQ(it[0], json(42));
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
TEST_F(JsonIteratorArithmeticTest, SubscriptValueConst)
|
||||
{
|
||||
auto it = j_value.cbegin();
|
||||
EXPECT_EQ(it[0], json(42));
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
#if 0
|
||||
TEST(JsonReverseIteratorTest, Comparisons)
|
||||
{
|
||||
json j_values = {nullptr, true, 42, 42u, 23.23, {{"one", 1}, {"two", 2}}, {1, 2, 3, 4, 5}, "Hello, world"};
|
||||
|
||||
for (json& j : j_values)
|
||||
{
|
||||
SCOPED_TRACE(j.dump());
|
||||
auto it1 = j.rbegin();
|
||||
auto it2 = j.rbegin();
|
||||
auto it3 = j.rbegin();
|
||||
++it2;
|
||||
++it3;
|
||||
++it3;
|
||||
auto it1_c = j.crbegin();
|
||||
auto it2_c = j.crbegin();
|
||||
auto it3_c = j.crbegin();
|
||||
++it2_c;
|
||||
++it3_c;
|
||||
++it3_c;
|
||||
|
||||
// comparison: equal
|
||||
{
|
||||
EXPECT_TRUE(it1 == it1);
|
||||
EXPECT_FALSE(it1 == it2);
|
||||
EXPECT_FALSE(it1 == it3);
|
||||
EXPECT_FALSE(it2 == it3);
|
||||
EXPECT_TRUE(it1_c == it1_c);
|
||||
EXPECT_FALSE(it1_c == it2_c);
|
||||
EXPECT_FALSE(it1_c == it3_c);
|
||||
EXPECT_FALSE(it2_c == it3_c);
|
||||
}
|
||||
|
||||
// comparison: not equal
|
||||
{
|
||||
// check definition
|
||||
EXPECT_EQ( (it1 != it1), !(it1 == it1) );
|
||||
EXPECT_EQ( (it1 != it2), !(it1 == it2) );
|
||||
EXPECT_EQ( (it1 != it3), !(it1 == it3) );
|
||||
EXPECT_EQ( (it2 != it3), !(it2 == it3) );
|
||||
EXPECT_EQ( (it1_c != it1_c), !(it1_c == it1_c) );
|
||||
EXPECT_EQ( (it1_c != it2_c), !(it1_c == it2_c) );
|
||||
EXPECT_EQ( (it1_c != it3_c), !(it1_c == it3_c) );
|
||||
EXPECT_EQ( (it2_c != it3_c), !(it2_c == it3_c) );
|
||||
}
|
||||
|
||||
// comparison: smaller
|
||||
{
|
||||
if (j.type() == json::value_t::object)
|
||||
{
|
||||
EXPECT_THROW_MSG(it1 < it1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 < it2, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2 < it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 < it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c < it1_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c < it2_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2_c < it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c < it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_FALSE(it1 < it1);
|
||||
EXPECT_TRUE(it1 < it2);
|
||||
EXPECT_TRUE(it1 < it3);
|
||||
EXPECT_TRUE(it2 < it3);
|
||||
EXPECT_FALSE(it1_c < it1_c);
|
||||
EXPECT_TRUE(it1_c < it2_c);
|
||||
EXPECT_TRUE(it1_c < it3_c);
|
||||
EXPECT_TRUE(it2_c < it3_c);
|
||||
}
|
||||
}
|
||||
|
||||
// comparison: less than or equal
|
||||
{
|
||||
if (j.type() == json::value_t::object)
|
||||
{
|
||||
EXPECT_THROW_MSG(it1 <= it1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 <= it2, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2 <= it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 <= it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c <= it1_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c <= it2_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2_c <= it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c <= it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
}
|
||||
else
|
||||
{
|
||||
// check definition
|
||||
EXPECT_EQ( (it1 <= it1), !(it1 < it1) );
|
||||
EXPECT_EQ( (it1 <= it2), !(it2 < it1) );
|
||||
EXPECT_EQ( (it1 <= it3), !(it3 < it1) );
|
||||
EXPECT_EQ( (it2 <= it3), !(it3 < it2) );
|
||||
EXPECT_EQ( (it1_c <= it1_c), !(it1_c < it1_c) );
|
||||
EXPECT_EQ( (it1_c <= it2_c), !(it2_c < it1_c) );
|
||||
EXPECT_EQ( (it1_c <= it3_c), !(it3_c < it1_c) );
|
||||
EXPECT_EQ( (it2_c <= it3_c), !(it3_c < it2_c) );
|
||||
}
|
||||
}
|
||||
|
||||
// comparison: greater than
|
||||
{
|
||||
if (j.type() == json::value_t::object)
|
||||
{
|
||||
EXPECT_THROW_MSG(it1 > it1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 > it2, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2 > it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 > it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c > it1_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c > it2_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2_c > it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c > it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
}
|
||||
else
|
||||
{
|
||||
// check definition
|
||||
EXPECT_EQ( (it1 > it1), (it1 < it1) );
|
||||
EXPECT_EQ( (it1 > it2), (it2 < it1) );
|
||||
EXPECT_EQ( (it1 > it3), (it3 < it1) );
|
||||
EXPECT_EQ( (it2 > it3), (it3 < it2) );
|
||||
EXPECT_EQ( (it1_c > it1_c), (it1_c < it1_c) );
|
||||
EXPECT_EQ( (it1_c > it2_c), (it2_c < it1_c) );
|
||||
EXPECT_EQ( (it1_c > it3_c), (it3_c < it1_c) );
|
||||
EXPECT_EQ( (it2_c > it3_c), (it3_c < it2_c) );
|
||||
}
|
||||
}
|
||||
|
||||
// comparison: greater than or equal
|
||||
{
|
||||
if (j.type() == json::value_t::object)
|
||||
{
|
||||
EXPECT_THROW_MSG(it1 >= it1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 >= it2, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2 >= it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1 >= it3, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c >= it1_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c >= it2_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it2_c >= it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
EXPECT_THROW_MSG(it1_c >= it3_c, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.213] cannot compare order of object iterators");
|
||||
}
|
||||
else
|
||||
{
|
||||
// check definition
|
||||
EXPECT_EQ( (it1 >= it1), !(it1 < it1) );
|
||||
EXPECT_EQ( (it1 >= it2), !(it1 < it2) );
|
||||
EXPECT_EQ( (it1 >= it3), !(it1 < it3) );
|
||||
EXPECT_EQ( (it2 >= it3), !(it2 < it3) );
|
||||
EXPECT_EQ( (it1_c >= it1_c), !(it1_c < it1_c) );
|
||||
EXPECT_EQ( (it1_c >= it2_c), !(it1_c < it2_c) );
|
||||
EXPECT_EQ( (it1_c >= it3_c), !(it1_c < it3_c) );
|
||||
EXPECT_EQ( (it2_c >= it3_c), !(it2_c < it3_c) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check exceptions if different objects are compared
|
||||
for (auto j : j_values)
|
||||
{
|
||||
for (auto k : j_values)
|
||||
{
|
||||
if (j != k)
|
||||
{
|
||||
EXPECT_THROW_MSG(j.rbegin() == k.rbegin(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
EXPECT_THROW_MSG(j.crbegin() == k.crbegin(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
|
||||
EXPECT_THROW_MSG(j.rbegin() < k.rbegin(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
EXPECT_THROW_MSG(j.crbegin() < k.crbegin(), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.212] cannot compare iterators of different containers");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JsonReverseIteratorArithmeticTest : public ::testing::Test {
|
||||
protected:
|
||||
json j_object = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
json j_array = {1, 2, 3, 4, 5, 6};
|
||||
json j_null = nullptr;
|
||||
json j_value = 42;
|
||||
};
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, AddSubObject)
|
||||
{
|
||||
{
|
||||
auto it = j_object.rbegin();
|
||||
EXPECT_THROW_MSG(it += 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.crbegin();
|
||||
EXPECT_THROW_MSG(it += 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.rbegin();
|
||||
EXPECT_THROW_MSG(it + 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.crbegin();
|
||||
EXPECT_THROW_MSG(it + 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.rbegin();
|
||||
EXPECT_THROW_MSG(1 + it, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.crbegin();
|
||||
EXPECT_THROW_MSG(1 + it, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.rbegin();
|
||||
EXPECT_THROW_MSG(it -= 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.crbegin();
|
||||
EXPECT_THROW_MSG(it -= 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.rbegin();
|
||||
EXPECT_THROW_MSG(it - 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.crbegin();
|
||||
EXPECT_THROW_MSG(it - 1, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.rbegin();
|
||||
EXPECT_THROW_MSG(it - it, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
{
|
||||
auto it = j_object.crbegin();
|
||||
EXPECT_THROW_MSG(it - it, json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, AddSubArray)
|
||||
{
|
||||
auto it = j_array.rbegin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_array.rbegin() + 3), it);
|
||||
EXPECT_EQ(json::reverse_iterator(3 + j_array.rbegin()), it);
|
||||
EXPECT_EQ((it - 3), j_array.rbegin());
|
||||
EXPECT_EQ((it - j_array.rbegin()), 3);
|
||||
EXPECT_EQ(*it, json(3));
|
||||
it -= 2;
|
||||
EXPECT_EQ(*it, json(5));
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, AddSubArrayConst)
|
||||
{
|
||||
auto it = j_array.crbegin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_array.crbegin() + 3), it);
|
||||
EXPECT_EQ(json::const_reverse_iterator(3 + j_array.crbegin()), it);
|
||||
EXPECT_EQ((it - 3), j_array.crbegin());
|
||||
EXPECT_EQ((it - j_array.crbegin()), 3);
|
||||
EXPECT_EQ(*it, json(3));
|
||||
it -= 2;
|
||||
EXPECT_EQ(*it, json(5));
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, AddSubNull)
|
||||
{
|
||||
auto it = j_null.rbegin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_null.rbegin() + 3), it);
|
||||
EXPECT_EQ(json::reverse_iterator(3 + j_null.rbegin()), it);
|
||||
EXPECT_EQ((it - 3), j_null.rbegin());
|
||||
EXPECT_EQ((it - j_null.rbegin()), 3);
|
||||
EXPECT_NE(it, j_null.rend());
|
||||
it -= 3;
|
||||
EXPECT_EQ(it, j_null.rend());
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, AddSubNullConst)
|
||||
{
|
||||
auto it = j_null.crbegin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_null.crbegin() + 3), it);
|
||||
EXPECT_EQ(json::const_reverse_iterator(3 + j_null.crbegin()), it);
|
||||
EXPECT_EQ((it - 3), j_null.crbegin());
|
||||
EXPECT_EQ((it - j_null.crbegin()), 3);
|
||||
EXPECT_NE(it, j_null.crend());
|
||||
it -= 3;
|
||||
EXPECT_EQ(it, j_null.crend());
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, AddSubValue)
|
||||
{
|
||||
auto it = j_value.rbegin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_value.rbegin() + 3), it);
|
||||
EXPECT_EQ(json::reverse_iterator(3 + j_value.rbegin()), it);
|
||||
EXPECT_EQ((it - 3), j_value.rbegin());
|
||||
EXPECT_EQ((it - j_value.rbegin()), 3);
|
||||
EXPECT_NE(it, j_value.rend());
|
||||
it -= 3;
|
||||
EXPECT_EQ(*it, json(42));
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, AddSubValueConst)
|
||||
{
|
||||
auto it = j_value.crbegin();
|
||||
it += 3;
|
||||
EXPECT_EQ((j_value.crbegin() + 3), it);
|
||||
EXPECT_EQ(json::const_reverse_iterator(3 + j_value.crbegin()), it);
|
||||
EXPECT_EQ((it - 3), j_value.crbegin());
|
||||
EXPECT_EQ((it - j_value.crbegin()), 3);
|
||||
EXPECT_NE(it, j_value.crend());
|
||||
it -= 3;
|
||||
EXPECT_EQ(*it, json(42));
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, SubscriptObject)
|
||||
{
|
||||
auto it = j_object.rbegin();
|
||||
EXPECT_THROW_MSG(it[0], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, SubscriptObjectConst)
|
||||
{
|
||||
auto it = j_object.crbegin();
|
||||
EXPECT_THROW_MSG(it[0], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, SubscriptArray)
|
||||
{
|
||||
auto it = j_array.rbegin();
|
||||
EXPECT_EQ(it[0], json(6));
|
||||
EXPECT_EQ(it[1], json(5));
|
||||
EXPECT_EQ(it[2], json(4));
|
||||
EXPECT_EQ(it[3], json(3));
|
||||
EXPECT_EQ(it[4], json(2));
|
||||
EXPECT_EQ(it[5], json(1));
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, SubscriptArrayConst)
|
||||
{
|
||||
auto it = j_array.crbegin();
|
||||
EXPECT_EQ(it[0], json(6));
|
||||
EXPECT_EQ(it[1], json(5));
|
||||
EXPECT_EQ(it[2], json(4));
|
||||
EXPECT_EQ(it[3], json(3));
|
||||
EXPECT_EQ(it[4], json(2));
|
||||
EXPECT_EQ(it[5], json(1));
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, SubscriptNull)
|
||||
{
|
||||
auto it = j_null.rbegin();
|
||||
EXPECT_THROW_MSG(it[0], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, SubscriptNullConst)
|
||||
{
|
||||
auto it = j_null.crbegin();
|
||||
EXPECT_THROW_MSG(it[0], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, SubscriptValue)
|
||||
{
|
||||
auto it = j_value.rbegin();
|
||||
EXPECT_EQ(it[0], json(42));
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
|
||||
TEST_F(JsonReverseIteratorArithmeticTest, SubscriptValueConst)
|
||||
{
|
||||
auto it = j_value.crbegin();
|
||||
EXPECT_EQ(it[0], json(42));
|
||||
EXPECT_THROW_MSG(it[1], json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.214] cannot get value");
|
||||
}
|
||||
#endif
|
||||
88
wpiutil/src/test/native/cpp/json/unit-json.h
Normal file
88
wpiutil/src/test/native/cpp/json/unit-json.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/#ifndef UNIT_JSON_H_
|
||||
#define UNIT_JSON_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "support/json.h"
|
||||
|
||||
namespace wpi {
|
||||
|
||||
inline
|
||||
void PrintTo(const json& j, std::ostream* os) {
|
||||
*os << j.dump();
|
||||
}
|
||||
|
||||
class JsonTest {
|
||||
public:
|
||||
static const json::json_value& GetValue(const json& j) {
|
||||
return j.m_value;
|
||||
}
|
||||
static json::pointer GetObject(json::iterator it) {
|
||||
return it.m_object;
|
||||
}
|
||||
static json::const_pointer GetObject(json::const_iterator it) {
|
||||
return it.m_object;
|
||||
}
|
||||
static std::string pop_back(json::json_pointer& p) {
|
||||
return p.pop_back();
|
||||
}
|
||||
static json::json_pointer top(const json::json_pointer& p) {
|
||||
return p.top();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace wpi
|
||||
|
||||
// clang warns on TEST_THROW_MSG(x == y, ...) saying the result is unused.
|
||||
// suppress this warning.
|
||||
#if defined(__clang__)
|
||||
#pragma GCC diagnostic ignored "-Wunused-comparison"
|
||||
#endif
|
||||
|
||||
// variant of GTEST_TEST_THROW_ that also checks the exception's message.
|
||||
#define TEST_THROW_MSG(statement, expected_exception, expected_msg, fail) \
|
||||
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
|
||||
if (::testing::internal::ConstCharPtr gtest_msg = "") { \
|
||||
bool gtest_caught_expected = false; \
|
||||
try { \
|
||||
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
|
||||
} \
|
||||
catch (expected_exception const& gtest_ex) { \
|
||||
gtest_caught_expected = true; \
|
||||
if (::std::string(gtest_ex.what()) != expected_msg) { \
|
||||
::testing::AssertionResult gtest_ar = ::testing::AssertionFailure(); \
|
||||
gtest_ar \
|
||||
<< "Expected: " #statement " throws an exception with message \"" \
|
||||
<< expected_msg "\".\n Actual: it throws message \"" \
|
||||
<< gtest_ex.what() << "\"."; \
|
||||
fail(gtest_ar.failure_message()); \
|
||||
} \
|
||||
} \
|
||||
catch (...) { \
|
||||
gtest_msg.value = \
|
||||
"Expected: " #statement " throws an exception of type " \
|
||||
#expected_exception ".\n Actual: it throws a different type."; \
|
||||
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
|
||||
} \
|
||||
if (!gtest_caught_expected) { \
|
||||
gtest_msg.value = \
|
||||
"Expected: " #statement " throws an exception of type " \
|
||||
#expected_exception ".\n Actual: it throws nothing."; \
|
||||
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
|
||||
} \
|
||||
} else \
|
||||
GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
|
||||
fail(gtest_msg.value)
|
||||
|
||||
#define EXPECT_THROW_MSG(statement, expected_exception, expected_msg) \
|
||||
TEST_THROW_MSG(statement, expected_exception, expected_msg, GTEST_NONFATAL_FAILURE_)
|
||||
|
||||
#define ASSERT_THROW_MSG(statement, expected_exception, expected_msg) \
|
||||
TEST_THROW_MSG(statement, expected_exception, expected_msg, GTEST_FATAL_FAILURE_)
|
||||
|
||||
#endif
|
||||
402
wpiutil/src/test/native/cpp/json/unit-json_pointer.cpp
Normal file
402
wpiutil/src/test/native/cpp/json/unit-json_pointer.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
using wpi::JsonTest;
|
||||
|
||||
TEST(JsonPointerTest, Errors)
|
||||
{
|
||||
EXPECT_THROW_MSG(json::json_pointer("foo"), json::parse_error,
|
||||
"[json.exception.parse_error.107] parse error at 1: JSON pointer must be empty or begin with '/' - was: 'foo'");
|
||||
|
||||
EXPECT_THROW_MSG(json::json_pointer("/~~"), json::parse_error,
|
||||
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'");
|
||||
|
||||
EXPECT_THROW_MSG(json::json_pointer("/~"), json::parse_error,
|
||||
"[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'");
|
||||
|
||||
json::json_pointer p;
|
||||
EXPECT_THROW_MSG(JsonTest::top(p), json::out_of_range,
|
||||
"[json.exception.out_of_range.405] JSON pointer has no parent");
|
||||
EXPECT_THROW_MSG(JsonTest::pop_back(p), json::out_of_range,
|
||||
"[json.exception.out_of_range.405] JSON pointer has no parent");
|
||||
}
|
||||
|
||||
// examples from RFC 6901
|
||||
TEST(JsonPointerTest, AccessNonConst)
|
||||
{
|
||||
json j = R"(
|
||||
{
|
||||
"foo": ["bar", "baz"],
|
||||
"": 0,
|
||||
"a/b": 1,
|
||||
"c%d": 2,
|
||||
"e^f": 3,
|
||||
"g|h": 4,
|
||||
"i\\j": 5,
|
||||
"k\"l": 6,
|
||||
" ": 7,
|
||||
"m~n": 8
|
||||
}
|
||||
)"_json;
|
||||
|
||||
// the whole document
|
||||
EXPECT_EQ(j[json::json_pointer()], j);
|
||||
EXPECT_EQ(j[json::json_pointer("")], j);
|
||||
|
||||
// array access
|
||||
EXPECT_EQ(j[json::json_pointer("/foo")], j["foo"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/foo/0")], j["foo"][0]);
|
||||
EXPECT_EQ(j[json::json_pointer("/foo/1")], j["foo"][1]);
|
||||
EXPECT_EQ(j["/foo/1"_json_pointer], j["foo"][1]);
|
||||
|
||||
// checked array access
|
||||
EXPECT_EQ(j.at(json::json_pointer("/foo/0")), j["foo"][0]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/foo/1")), j["foo"][1]);
|
||||
|
||||
// empty string access
|
||||
EXPECT_EQ(j[json::json_pointer("/")], j[""]);
|
||||
|
||||
// other cases
|
||||
EXPECT_EQ(j[json::json_pointer("/ ")], j[" "]);
|
||||
EXPECT_EQ(j[json::json_pointer("/c%d")], j["c%d"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/e^f")], j["e^f"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/g|h")], j["g|h"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/i\\j")], j["i\\j"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/k\"l")], j["k\"l"]);
|
||||
|
||||
// checked access
|
||||
EXPECT_EQ(j.at(json::json_pointer("/ ")), j[" "]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/c%d")), j["c%d"]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/e^f")), j["e^f"]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/g|h")), j["g|h"]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/i\\j")), j["i\\j"]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/k\"l")), j["k\"l"]);
|
||||
|
||||
// escaped access
|
||||
EXPECT_EQ(j[json::json_pointer("/a~1b")], j["a/b"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/m~0n")], j["m~n"]);
|
||||
|
||||
// unescaped access
|
||||
// access to nonexisting values yield object creation
|
||||
EXPECT_NO_THROW(j[json::json_pointer("/a/b")] = 42);
|
||||
EXPECT_EQ(j["a"]["b"], json(42));
|
||||
EXPECT_NO_THROW(j[json::json_pointer("/a/c/1")] = 42);
|
||||
EXPECT_EQ(j["a"]["c"], json({nullptr, 42}));
|
||||
EXPECT_NO_THROW(j[json::json_pointer("/a/d/-")] = 42);
|
||||
EXPECT_EQ(j["a"]["d"], json::array({42}));
|
||||
// "/a/b" works for JSON {"a": {"b": 42}}
|
||||
EXPECT_EQ(json({{"a", {{"b", 42}}}})[json::json_pointer("/a/b")], json(42));
|
||||
|
||||
// unresolved access
|
||||
json j_primitive = 1;
|
||||
EXPECT_THROW_MSG(j_primitive["/foo"_json_pointer], json::out_of_range,
|
||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'");
|
||||
EXPECT_THROW_MSG(j_primitive.at("/foo"_json_pointer), json::out_of_range,
|
||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'");
|
||||
}
|
||||
|
||||
TEST(JsonPointerTest, AccessConst)
|
||||
{
|
||||
const json j = R"(
|
||||
{
|
||||
"foo": ["bar", "baz"],
|
||||
"": 0,
|
||||
"a/b": 1,
|
||||
"c%d": 2,
|
||||
"e^f": 3,
|
||||
"g|h": 4,
|
||||
"i\\j": 5,
|
||||
"k\"l": 6,
|
||||
" ": 7,
|
||||
"m~n": 8
|
||||
}
|
||||
)"_json;
|
||||
|
||||
// the whole document
|
||||
EXPECT_EQ(j[json::json_pointer()], j);
|
||||
EXPECT_EQ(j[json::json_pointer("")], j);
|
||||
|
||||
// array access
|
||||
EXPECT_EQ(j[json::json_pointer("/foo")], j["foo"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/foo/0")], j["foo"][0]);
|
||||
EXPECT_EQ(j[json::json_pointer("/foo/1")], j["foo"][1]);
|
||||
EXPECT_EQ(j["/foo/1"_json_pointer], j["foo"][1]);
|
||||
|
||||
// checked array access
|
||||
EXPECT_EQ(j.at(json::json_pointer("/foo/0")), j["foo"][0]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/foo/1")), j["foo"][1]);
|
||||
|
||||
// empty string access
|
||||
EXPECT_EQ(j[json::json_pointer("/")], j[""]);
|
||||
|
||||
// other cases
|
||||
EXPECT_EQ(j[json::json_pointer("/ ")], j[" "]);
|
||||
EXPECT_EQ(j[json::json_pointer("/c%d")], j["c%d"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/e^f")], j["e^f"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/g|h")], j["g|h"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/i\\j")], j["i\\j"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/k\"l")], j["k\"l"]);
|
||||
|
||||
// checked access
|
||||
EXPECT_EQ(j.at(json::json_pointer("/ ")), j[" "]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/c%d")), j["c%d"]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/e^f")), j["e^f"]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/g|h")), j["g|h"]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/i\\j")), j["i\\j"]);
|
||||
EXPECT_EQ(j.at(json::json_pointer("/k\"l")), j["k\"l"]);
|
||||
|
||||
// escaped access
|
||||
EXPECT_EQ(j[json::json_pointer("/a~1b")], j["a/b"]);
|
||||
EXPECT_EQ(j[json::json_pointer("/m~0n")], j["m~n"]);
|
||||
|
||||
// unescaped access
|
||||
EXPECT_THROW_MSG(j.at(json::json_pointer("/a/b")), json::out_of_range,
|
||||
"[json.exception.out_of_range.403] key 'a' not found");
|
||||
|
||||
// unresolved access
|
||||
const json j_primitive = 1;
|
||||
EXPECT_THROW_MSG(j_primitive["/foo"_json_pointer], json::out_of_range,
|
||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'");
|
||||
EXPECT_THROW_MSG(j_primitive.at("/foo"_json_pointer), json::out_of_range,
|
||||
"[json.exception.out_of_range.404] unresolved reference token 'foo'");
|
||||
}
|
||||
|
||||
TEST(JsonPointerTest, UserStringLiteral)
|
||||
{
|
||||
json j = R"(
|
||||
{
|
||||
"foo": ["bar", "baz"],
|
||||
"": 0,
|
||||
"a/b": 1,
|
||||
"c%d": 2,
|
||||
"e^f": 3,
|
||||
"g|h": 4,
|
||||
"i\\j": 5,
|
||||
"k\"l": 6,
|
||||
" ": 7,
|
||||
"m~n": 8
|
||||
}
|
||||
)"_json;
|
||||
|
||||
// the whole document
|
||||
EXPECT_EQ(j[""_json_pointer], j);
|
||||
|
||||
// array access
|
||||
EXPECT_EQ(j["/foo"_json_pointer], j["foo"]);
|
||||
EXPECT_EQ(j["/foo/0"_json_pointer], j["foo"][0]);
|
||||
EXPECT_EQ(j["/foo/1"_json_pointer], j["foo"][1]);
|
||||
}
|
||||
|
||||
TEST(JsonPointerTest, ArrayNonConst)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
const json j_const = j;
|
||||
|
||||
// check reading access
|
||||
EXPECT_EQ(j["/0"_json_pointer], j[0]);
|
||||
EXPECT_EQ(j["/1"_json_pointer], j[1]);
|
||||
EXPECT_EQ(j["/2"_json_pointer], j[2]);
|
||||
|
||||
// assign to existing index
|
||||
j["/1"_json_pointer] = 13;
|
||||
EXPECT_EQ(j[1], json(13));
|
||||
|
||||
// assign to nonexisting index
|
||||
j["/3"_json_pointer] = 33;
|
||||
EXPECT_EQ(j[3], json(33));
|
||||
|
||||
// assign to nonexisting index (with gap)
|
||||
j["/5"_json_pointer] = 55;
|
||||
EXPECT_EQ(j, json({1, 13, 3, 33, nullptr, 55}));
|
||||
|
||||
// error with leading 0
|
||||
EXPECT_THROW_MSG(j["/01"_json_pointer], json::parse_error,
|
||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
|
||||
EXPECT_THROW_MSG(j_const["/01"_json_pointer], json::parse_error,
|
||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
|
||||
EXPECT_THROW_MSG(j.at("/01"_json_pointer), json::parse_error,
|
||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
|
||||
EXPECT_THROW_MSG(j_const.at("/01"_json_pointer), json::parse_error,
|
||||
"[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'");
|
||||
|
||||
// error with incorrect numbers
|
||||
EXPECT_THROW_MSG(j["/one"_json_pointer] = 1, json::parse_error,
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
EXPECT_THROW_MSG(j_const["/one"_json_pointer] == 1, json::parse_error,
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
|
||||
EXPECT_THROW_MSG(j.at("/one"_json_pointer) = 1, json::parse_error,
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
EXPECT_THROW_MSG(j_const.at("/one"_json_pointer) == 1, json::parse_error,
|
||||
"[json.exception.parse_error.109] parse error: array index 'one' is not a number");
|
||||
|
||||
EXPECT_THROW_MSG(json({{"/list/0", 1}, {"/list/1", 2}, {"/list/three", 3}}).unflatten(), json::parse_error,
|
||||
"[json.exception.parse_error.109] parse error: array index 'three' is not a number");
|
||||
|
||||
// assign to "-"
|
||||
j["/-"_json_pointer] = 99;
|
||||
EXPECT_EQ(j, json({1, 13, 3, 33, nullptr, 55, 99}));
|
||||
|
||||
// error when using "-" in const object
|
||||
EXPECT_THROW_MSG(j_const["/-"_json_pointer], json::out_of_range,
|
||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
|
||||
|
||||
// error when using "-" with at
|
||||
EXPECT_THROW_MSG(j.at("/-"_json_pointer), json::out_of_range,
|
||||
"[json.exception.out_of_range.402] array index '-' (7) is out of range");
|
||||
EXPECT_THROW_MSG(j_const.at("/-"_json_pointer), json::out_of_range,
|
||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
|
||||
}
|
||||
|
||||
TEST(JsonPointerTest, ArrayConst)
|
||||
{
|
||||
const json j = {1, 2, 3};
|
||||
|
||||
// check reading access
|
||||
EXPECT_EQ(j["/0"_json_pointer], j[0]);
|
||||
EXPECT_EQ(j["/1"_json_pointer], j[1]);
|
||||
EXPECT_EQ(j["/2"_json_pointer], j[2]);
|
||||
|
||||
// assign to nonexisting index
|
||||
EXPECT_THROW_MSG(j.at("/3"_json_pointer), json::out_of_range,
|
||||
"[json.exception.out_of_range.401] array index 3 is out of range");
|
||||
|
||||
// assign to nonexisting index (with gap)
|
||||
EXPECT_THROW_MSG(j.at("/5"_json_pointer), json::out_of_range,
|
||||
"[json.exception.out_of_range.401] array index 5 is out of range");
|
||||
|
||||
// assign to "-"
|
||||
EXPECT_THROW_MSG(j["/-"_json_pointer], json::out_of_range,
|
||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
|
||||
EXPECT_THROW_MSG(j.at("/-"_json_pointer), json::out_of_range,
|
||||
"[json.exception.out_of_range.402] array index '-' (3) is out of range");
|
||||
}
|
||||
|
||||
TEST(JsonPointerTest, Flatten)
|
||||
{
|
||||
json j =
|
||||
{
|
||||
{"pi", 3.141},
|
||||
{"happy", true},
|
||||
{"name", "Niels"},
|
||||
{"nothing", nullptr},
|
||||
{
|
||||
"answer", {
|
||||
{"everything", 42}
|
||||
}
|
||||
},
|
||||
{"list", {1, 0, 2}},
|
||||
{
|
||||
"object", {
|
||||
{"currency", "USD"},
|
||||
{"value", 42.99},
|
||||
{"", "empty string"},
|
||||
{"/", "slash"},
|
||||
{"~", "tilde"},
|
||||
{"~1", "tilde1"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
json j_flatten =
|
||||
{
|
||||
{"/pi", 3.141},
|
||||
{"/happy", true},
|
||||
{"/name", "Niels"},
|
||||
{"/nothing", nullptr},
|
||||
{"/answer/everything", 42},
|
||||
{"/list/0", 1},
|
||||
{"/list/1", 0},
|
||||
{"/list/2", 2},
|
||||
{"/object/currency", "USD"},
|
||||
{"/object/value", 42.99},
|
||||
{"/object/", "empty string"},
|
||||
{"/object/~1", "slash"},
|
||||
{"/object/~0", "tilde"},
|
||||
{"/object/~01", "tilde1"}
|
||||
};
|
||||
|
||||
// check if flattened result is as expected
|
||||
EXPECT_EQ(j.flatten(), j_flatten);
|
||||
|
||||
// check if unflattened result is as expected
|
||||
EXPECT_EQ(j_flatten.unflatten(), j);
|
||||
|
||||
// error for nonobjects
|
||||
EXPECT_THROW_MSG(json(1).unflatten(), json::type_error,
|
||||
"[json.exception.type_error.314] only objects can be unflattened");
|
||||
|
||||
// error for nonprimitve values
|
||||
EXPECT_THROW_MSG(json({{"/1", {1, 2, 3}}}).unflatten(), json::type_error,
|
||||
"[json.exception.type_error.315] values in object must be primitive");
|
||||
|
||||
// error for conflicting values
|
||||
json j_error = {{"", 42}, {"/foo", 17}};
|
||||
EXPECT_THROW_MSG(j_error.unflatten(), json::type_error,
|
||||
"[json.exception.type_error.313] invalid value to unflatten");
|
||||
|
||||
// explicit roundtrip check
|
||||
EXPECT_EQ(j.flatten().unflatten(), j);
|
||||
|
||||
// roundtrip for primitive values
|
||||
json j_null;
|
||||
EXPECT_EQ(j_null.flatten().unflatten(), j_null);
|
||||
json j_number = 42;
|
||||
EXPECT_EQ(j_number.flatten().unflatten(), j_number);
|
||||
json j_boolean = false;
|
||||
EXPECT_EQ(j_boolean.flatten().unflatten(), j_boolean);
|
||||
json j_string = "foo";
|
||||
EXPECT_EQ(j_string.flatten().unflatten(), j_string);
|
||||
|
||||
// roundtrip for empty structured values (will be unflattened to null)
|
||||
json j_array(json::value_t::array);
|
||||
EXPECT_EQ(j_array.flatten().unflatten(), json());
|
||||
json j_object(json::value_t::object);
|
||||
EXPECT_EQ(j_object.flatten().unflatten(), json());
|
||||
}
|
||||
|
||||
TEST(JsonPointerTest, StringRepresentation)
|
||||
{
|
||||
for (auto ptr :
|
||||
{"", "/foo", "/foo/0", "/", "/a~1b", "/c%d", "/e^f", "/g|h", "/i\\j", "/k\"l", "/ ", "/m~0n"
|
||||
})
|
||||
{
|
||||
SCOPED_TRACE(ptr);
|
||||
EXPECT_EQ(json::json_pointer(ptr).to_string(), ptr);
|
||||
}
|
||||
}
|
||||
54
wpiutil/src/test/native/cpp/json/unit-meta.cpp
Normal file
54
wpiutil/src/test/native/cpp/json/unit-meta.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2016 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
TEST(JsonVersionTest, Meta)
|
||||
{
|
||||
json j = json::meta();
|
||||
|
||||
EXPECT_EQ(j["name"], "WPI version of JSON for Modern C++");
|
||||
EXPECT_EQ(j["copyright"], "(C) 2013-2017 Niels Lohmann, (C) 2017 FIRST");
|
||||
EXPECT_EQ(j["url"], "https://github.com/wpilibsuite/wpiutil");
|
||||
EXPECT_EQ(j["version"], json(
|
||||
{
|
||||
{"string", "2.1.1"},
|
||||
{"major", 2},
|
||||
{"minor", 1},
|
||||
{"patch", 1}
|
||||
}));
|
||||
}
|
||||
739
wpiutil/src/test/native/cpp/json/unit-modifiers.cpp
Normal file
739
wpiutil/src/test/native/cpp/json/unit-modifiers.cpp
Normal file
@@ -0,0 +1,739 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
TEST(JsonClearTest, Boolean)
|
||||
{
|
||||
json j = true;
|
||||
|
||||
j.clear();
|
||||
EXPECT_EQ(j, json(json::value_t::boolean));
|
||||
}
|
||||
|
||||
TEST(JsonClearTest, String)
|
||||
{
|
||||
json j = "hello world";
|
||||
|
||||
j.clear();
|
||||
EXPECT_EQ(j, json(json::value_t::string));
|
||||
}
|
||||
|
||||
TEST(JsonClearTest, ArrayEmpty)
|
||||
{
|
||||
json j = json::array();
|
||||
|
||||
j.clear();
|
||||
EXPECT_TRUE(j.empty());
|
||||
EXPECT_EQ(j, json(json::value_t::array));
|
||||
}
|
||||
|
||||
TEST(JsonClearTest, ArrayFilled)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
|
||||
j.clear();
|
||||
EXPECT_TRUE(j.empty());
|
||||
EXPECT_EQ(j, json(json::value_t::array));
|
||||
}
|
||||
|
||||
TEST(JsonClearTest, ObjectEmpty)
|
||||
{
|
||||
json j = json::object();
|
||||
|
||||
j.clear();
|
||||
EXPECT_TRUE(j.empty());
|
||||
EXPECT_EQ(j, json(json::value_t::object));
|
||||
}
|
||||
|
||||
TEST(JsonClearTest, ObjectFilled)
|
||||
{
|
||||
json j = {{"one", 1}, {"two", 2}, {"three", 3}};
|
||||
|
||||
j.clear();
|
||||
EXPECT_TRUE(j.empty());
|
||||
EXPECT_EQ(j, json(json::value_t::object));
|
||||
}
|
||||
|
||||
TEST(JsonClearTest, Integer)
|
||||
{
|
||||
json j = 23;
|
||||
|
||||
j.clear();
|
||||
EXPECT_EQ(j, json(json::value_t::number_integer));
|
||||
}
|
||||
|
||||
TEST(JsonClearTest, Unsigned)
|
||||
{
|
||||
json j = 23u;
|
||||
|
||||
j.clear();
|
||||
EXPECT_EQ(j, json(json::value_t::number_integer));
|
||||
}
|
||||
|
||||
TEST(JsonClearTest, Float)
|
||||
{
|
||||
json j = 23.42;
|
||||
|
||||
j.clear();
|
||||
EXPECT_EQ(j, json(json::value_t::number_float));
|
||||
}
|
||||
|
||||
TEST(JsonClearTest, Null)
|
||||
{
|
||||
json j = nullptr;
|
||||
|
||||
j.clear();
|
||||
EXPECT_EQ(j, json(json::value_t::null));
|
||||
}
|
||||
|
||||
TEST(JsonPushBackArrayTest, RRefNull)
|
||||
{
|
||||
json j;
|
||||
j.push_back(1);
|
||||
j.push_back(2);
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({1, 2}));
|
||||
}
|
||||
|
||||
TEST(JsonPushBackArrayTest, RRefArray)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
j.push_back("Hello");
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({1, 2, 3, "Hello"}));
|
||||
}
|
||||
|
||||
TEST(JsonPushBackArrayTest, RRefOther)
|
||||
{
|
||||
json j = 1;
|
||||
EXPECT_THROW_MSG(j.push_back("Hello"), json::type_error,
|
||||
"[json.exception.type_error.308] cannot use push_back() with number");
|
||||
}
|
||||
|
||||
TEST(JsonPushBackArrayTest, LRefNull)
|
||||
{
|
||||
json j;
|
||||
json k(1);
|
||||
j.push_back(k);
|
||||
j.push_back(k);
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({1, 1}));
|
||||
}
|
||||
|
||||
TEST(JsonPushBackArrayTest, LRefArray)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
json k("Hello");
|
||||
j.push_back(k);
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({1, 2, 3, "Hello"}));
|
||||
}
|
||||
|
||||
TEST(JsonPushBackArrayTest, LRefOther)
|
||||
{
|
||||
json j = 1;
|
||||
json k("Hello");
|
||||
EXPECT_THROW_MSG(j.push_back(k), json::type_error,
|
||||
"[json.exception.type_error.308] cannot use push_back() with number");
|
||||
}
|
||||
#if 0
|
||||
TEST(JsonPushBackObjectTest, Null)
|
||||
{
|
||||
json j;
|
||||
j.push_back(json::object_t::value_type({"one", 1}));
|
||||
j.push_back(json::object_t::value_type({"two", 2}));
|
||||
EXPECT_EQ(j.type(), json::value_t::object);
|
||||
EXPECT_EQ(j.size(), 2u);
|
||||
EXPECT_EQ(j["one"], json(1));
|
||||
EXPECT_EQ(j["two"], json(2));
|
||||
}
|
||||
|
||||
TEST(JsonPushBackObjectTest, Object)
|
||||
{
|
||||
json j(json::value_t::object);
|
||||
j.push_back(json::object_t::value_type({"one", 1}));
|
||||
j.push_back(json::object_t::value_type({"two", 2}));
|
||||
EXPECT_EQ(j.size(), 2u);
|
||||
EXPECT_EQ(j["one"], json(1));
|
||||
EXPECT_EQ(j["two"], json(2));
|
||||
}
|
||||
|
||||
TEST(JsonPushBackObjectTest, Other)
|
||||
{
|
||||
json j = 1;
|
||||
json k("Hello");
|
||||
EXPECT_THROW_MSG(j.push_back(json::object_t::value_type({"one", 1})), json::type_error,
|
||||
"[json.exception.type_error.308] cannot use push_back() with number");
|
||||
}
|
||||
#endif
|
||||
TEST(JsonPushBackInitListTest, Null)
|
||||
{
|
||||
json j;
|
||||
j.push_back({"foo", "bar"});
|
||||
EXPECT_EQ(j, json::array({{"foo", "bar"}}));
|
||||
|
||||
json k;
|
||||
k.push_back({1, 2, 3});
|
||||
EXPECT_EQ(k, json::array({{1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST(JsonPushBackInitListTest, Array)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
j.push_back({"foo", "bar"});
|
||||
EXPECT_EQ(j, json({1, 2, 3, {"foo", "bar"}}));
|
||||
|
||||
json k = {1, 2, 3};
|
||||
k.push_back({1, 2, 3});
|
||||
EXPECT_EQ(k, json({1, 2, 3, {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST(JsonPushBackInitListTest, Object)
|
||||
{
|
||||
json j = {{"key1", 1}};
|
||||
j.push_back({"key2", "bar"});
|
||||
EXPECT_EQ(j, json({{"key1", 1}, {"key2", "bar"}}));
|
||||
|
||||
json k = {{"key1", 1}};
|
||||
EXPECT_THROW_MSG(k.push_back({1, 2, 3, 4}), json::type_error,
|
||||
"[json.exception.type_error.308] cannot use push_back() with object");
|
||||
}
|
||||
|
||||
TEST(JsonEmplaceBackArrayTest, Null)
|
||||
{
|
||||
json j;
|
||||
j.emplace_back(1);
|
||||
j.emplace_back(2);
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({1, 2}));
|
||||
}
|
||||
|
||||
TEST(JsonEmplaceBackArrayTest, Array)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
j.emplace_back("Hello");
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({1, 2, 3, "Hello"}));
|
||||
}
|
||||
|
||||
TEST(JsonEmplaceBackArrayTest, MultipleValues)
|
||||
{
|
||||
json j;
|
||||
j.emplace_back(3, "foo");
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({{"foo", "foo", "foo"}}));
|
||||
}
|
||||
|
||||
TEST(JsonEmplaceBackArrayTest, Other)
|
||||
{
|
||||
json j = 1;
|
||||
EXPECT_THROW_MSG(j.emplace_back("Hello"), json::type_error,
|
||||
"[json.exception.type_error.311] cannot use emplace_back() with number");
|
||||
}
|
||||
|
||||
TEST(JsonEmplaceObjectTest, Null)
|
||||
{
|
||||
// start with a null value
|
||||
json j;
|
||||
|
||||
// add a new key
|
||||
auto res1 = j.emplace("foo", "bar");
|
||||
EXPECT_EQ(res1.second, true);
|
||||
EXPECT_EQ(*res1.first, "bar");
|
||||
|
||||
// the null value is changed to an object
|
||||
EXPECT_EQ(j.type(), json::value_t::object);
|
||||
|
||||
// add a new key
|
||||
auto res2 = j.emplace("baz", "bam");
|
||||
EXPECT_EQ(res2.second, true);
|
||||
EXPECT_EQ(*res2.first, "bam");
|
||||
|
||||
// we try to insert at given key - no change
|
||||
auto res3 = j.emplace("baz", "bad");
|
||||
EXPECT_EQ(res3.second, false);
|
||||
EXPECT_EQ(*res3.first, "bam");
|
||||
|
||||
// the final object
|
||||
EXPECT_EQ(j, json({{"baz", "bam"}, {"foo", "bar"}}));
|
||||
}
|
||||
|
||||
TEST(JsonEmplaceObjectTest, Object)
|
||||
{
|
||||
// start with an object
|
||||
json j = {{"foo", "bar"}};
|
||||
|
||||
// add a new key
|
||||
auto res1 = j.emplace("baz", "bam");
|
||||
EXPECT_EQ(res1.second, true);
|
||||
EXPECT_EQ(*res1.first, "bam");
|
||||
|
||||
// add an existing key
|
||||
auto res2 = j.emplace("foo", "bad");
|
||||
EXPECT_EQ(res2.second, false);
|
||||
EXPECT_EQ(*res2.first, "bar");
|
||||
|
||||
// check final object
|
||||
EXPECT_EQ(j, json({{"baz", "bam"}, {"foo", "bar"}}));
|
||||
}
|
||||
|
||||
TEST(JsonEmplaceObjectTest, Other)
|
||||
{
|
||||
json j = 1;
|
||||
EXPECT_THROW_MSG(j.emplace("foo", "bar"), json::type_error,
|
||||
"[json.exception.type_error.311] cannot use emplace() with number");
|
||||
}
|
||||
|
||||
TEST(JsonPlusEqualArrayTest, RRefNull)
|
||||
{
|
||||
json j;
|
||||
j += 1;
|
||||
j += 2;
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({1, 2}));
|
||||
}
|
||||
|
||||
TEST(JsonPlusEqualArrayTest, RRefArray)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
j += "Hello";
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({1, 2, 3, "Hello"}));
|
||||
}
|
||||
|
||||
TEST(JsonPlusEqualArrayTest, RRefOther)
|
||||
{
|
||||
json j = 1;
|
||||
EXPECT_THROW_MSG(j += "Hello", json::type_error,
|
||||
"[json.exception.type_error.308] cannot use push_back() with number");
|
||||
}
|
||||
|
||||
TEST(JsonPlusEqualArrayTest, LRefNull)
|
||||
{
|
||||
json j;
|
||||
json k(1);
|
||||
j += k;
|
||||
j += k;
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({1, 1}));
|
||||
}
|
||||
|
||||
TEST(JsonPlusEqualArrayTest, LRefArray)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
json k("Hello");
|
||||
j += k;
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
EXPECT_EQ(j, json({1, 2, 3, "Hello"}));
|
||||
}
|
||||
|
||||
TEST(JsonPlusEqualArrayTest, LRefOther)
|
||||
{
|
||||
json j = 1;
|
||||
json k("Hello");
|
||||
EXPECT_THROW_MSG(j += k, json::type_error,
|
||||
"[json.exception.type_error.308] cannot use push_back() with number");
|
||||
}
|
||||
#if 0
|
||||
TEST(JsonPlusEqualObjectTest, Null)
|
||||
{
|
||||
json j;
|
||||
j += json::object_t::value_type({"one", 1});
|
||||
j += json::object_t::value_type({"two", 2});
|
||||
EXPECT_EQ(j.type(), json::value_t::object);
|
||||
EXPECT_EQ(j.size(), 2u);
|
||||
EXPECT_EQ(j["one"], json(1));
|
||||
EXPECT_EQ(j["two"], json(2));
|
||||
}
|
||||
|
||||
TEST(JsonPlusEqualObjectTest, Object)
|
||||
{
|
||||
json j(json::value_t::object);
|
||||
j += json::object_t::value_type({"one", 1});
|
||||
j += json::object_t::value_type({"two", 2});
|
||||
EXPECT_EQ(j.size(), 2u);
|
||||
EXPECT_EQ(j["one"], json(1));
|
||||
EXPECT_EQ(j["two"], json(2));
|
||||
}
|
||||
|
||||
TEST(JsonPlusEqualObjectTest, Other)
|
||||
{
|
||||
json j = 1;
|
||||
json k("Hello");
|
||||
EXPECT_THROW_MSG(j += json::object_t::value_type({"one", 1}), json::type_error,
|
||||
"[json.exception.type_error.308] cannot use push_back() with number");
|
||||
}
|
||||
#endif
|
||||
TEST(JsonPlusEqualInitListTest, Null)
|
||||
{
|
||||
json j;
|
||||
j += {"foo", "bar"};
|
||||
EXPECT_EQ(j, json::array({{"foo", "bar"}}));
|
||||
|
||||
json k;
|
||||
k += {1, 2, 3};
|
||||
EXPECT_EQ(k, json::array({{1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST(JsonPlusEqualInitListTest, Array)
|
||||
{
|
||||
json j = {1, 2, 3};
|
||||
j += {"foo", "bar"};
|
||||
EXPECT_EQ(j, json({1, 2, 3, {"foo", "bar"}}));
|
||||
|
||||
json k = {1, 2, 3};
|
||||
k += {1, 2, 3};
|
||||
EXPECT_EQ(k, json({1, 2, 3, {1, 2, 3}}));
|
||||
}
|
||||
|
||||
TEST(JsonPlusEqualInitListTest, Object)
|
||||
{
|
||||
json j = {{"key1", 1}};
|
||||
j += {"key2", "bar"};
|
||||
EXPECT_EQ(j, json({{"key1", 1}, {"key2", "bar"}}));
|
||||
|
||||
json k = {{"key1", 1}};
|
||||
EXPECT_THROW_MSG((k += {1, 2, 3, 4}), json::type_error,
|
||||
"[json.exception.type_error.308] cannot use push_back() with object");
|
||||
}
|
||||
|
||||
class JsonInsertTest : public ::testing::Test {
|
||||
protected:
|
||||
json j_array = {1, 2, 3, 4};
|
||||
json j_value = 5;
|
||||
json j_other_array = {"first", "second"};
|
||||
json j_object1 = {{"one", "eins"}, {"two", "zwei"}};
|
||||
json j_object2 = {{"eleven", "elf"}, {"seventeen", "siebzehn"}};
|
||||
};
|
||||
|
||||
TEST_F(JsonInsertTest, ValueBegin)
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin(), j_value);
|
||||
EXPECT_EQ(j_array.size(), 5u);
|
||||
EXPECT_EQ(*it, j_value);
|
||||
EXPECT_EQ(j_array.begin(), it);
|
||||
EXPECT_EQ(j_array, json({5, 1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, ValueMiddle)
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin() + 2, j_value);
|
||||
EXPECT_EQ(j_array.size(), 5u);
|
||||
EXPECT_EQ(*it, j_value);
|
||||
EXPECT_EQ((it - j_array.begin()), 2);
|
||||
EXPECT_EQ(j_array, json({1, 2, 5, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, ValueEnd)
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), j_value);
|
||||
EXPECT_EQ(j_array.size(), 5u);
|
||||
EXPECT_EQ(*it, j_value);
|
||||
EXPECT_EQ((j_array.end() - it), 1);
|
||||
EXPECT_EQ(j_array, json({1, 2, 3, 4, 5}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, RvalueBegin)
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin(), 5);
|
||||
EXPECT_EQ(j_array.size(), 5u);
|
||||
EXPECT_EQ(*it, j_value);
|
||||
EXPECT_EQ(j_array.begin(), it);
|
||||
EXPECT_EQ(j_array, json({5, 1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, RvalueMiddle)
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin() + 2, 5);
|
||||
EXPECT_EQ(j_array.size(), 5u);
|
||||
EXPECT_EQ(*it, j_value);
|
||||
EXPECT_EQ((it - j_array.begin()), 2);
|
||||
EXPECT_EQ(j_array, json({1, 2, 5, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, RvalueEnd)
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), 5);
|
||||
EXPECT_EQ(j_array.size(), 5u);
|
||||
EXPECT_EQ(*it, j_value);
|
||||
EXPECT_EQ((j_array.end() - it), 1);
|
||||
EXPECT_EQ(j_array, json({1, 2, 3, 4, 5}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, CopyBegin)
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin(), 3, 5);
|
||||
EXPECT_EQ(j_array.size(), 7u);
|
||||
EXPECT_EQ(*it, j_value);
|
||||
EXPECT_EQ(j_array.begin(), it);
|
||||
EXPECT_EQ(j_array, json({5, 5, 5, 1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, CopyMiddle)
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin() + 2, 3, 5);
|
||||
EXPECT_EQ(j_array.size(), 7u);
|
||||
EXPECT_EQ(*it, j_value);
|
||||
EXPECT_EQ((it - j_array.begin()), 2);
|
||||
EXPECT_EQ(j_array, json({1, 2, 5, 5, 5, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, CopyEnd)
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), 3, 5);
|
||||
EXPECT_EQ(j_array.size(), 7u);
|
||||
EXPECT_EQ(*it, j_value);
|
||||
EXPECT_EQ((j_array.end() - it), 3);
|
||||
EXPECT_EQ(j_array, json({1, 2, 3, 4, 5, 5, 5}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, CopyNothing)
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), 0, 5);
|
||||
EXPECT_EQ(j_array.size(), 4u);
|
||||
// the returned iterator points to the first inserted element;
|
||||
// there were 4 elements, so it should point to the 5th
|
||||
EXPECT_EQ(it, j_array.begin() + 4);
|
||||
EXPECT_EQ(j_array, json({1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, RangeForArrayProper)
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.end());
|
||||
EXPECT_EQ(j_array.size(), 6u);
|
||||
EXPECT_EQ(*it, *j_other_array.begin());
|
||||
EXPECT_EQ((j_array.end() - it), 2);
|
||||
EXPECT_EQ(j_array, json({1, 2, 3, 4, "first", "second"}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, RangeForArrayEmpty)
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), j_other_array.begin(), j_other_array.begin());
|
||||
EXPECT_EQ(j_array.size(), 4u);
|
||||
EXPECT_EQ(it, j_array.end());
|
||||
EXPECT_EQ(j_array, json({1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, RangeForArrayInvalid)
|
||||
{
|
||||
json j_other_array2 = {"first", "second"};
|
||||
|
||||
EXPECT_THROW_MSG(j_array.insert(j_array.end(), j_array.begin(), j_array.end()),
|
||||
json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.211] passed iterators may not belong to container");
|
||||
EXPECT_THROW_MSG(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()),
|
||||
json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.210] iterators do not fit");
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, RangeForObjectProper)
|
||||
{
|
||||
j_object1.insert(j_object2.begin(), j_object2.end());
|
||||
EXPECT_EQ(j_object1.size(), 4u);
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, RangeForObjectEmpty)
|
||||
{
|
||||
j_object1.insert(j_object2.begin(), j_object2.begin());
|
||||
EXPECT_EQ(j_object1.size(), 2u);
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, RangeForObjectInvalid)
|
||||
{
|
||||
json j_other_array2 = {"first", "second"};
|
||||
|
||||
EXPECT_THROW_MSG(j_array.insert(j_object2.begin(), j_object2.end()), json::type_error,
|
||||
"[json.exception.type_error.309] cannot use insert() with array");
|
||||
EXPECT_THROW_MSG(j_object1.insert(j_object1.begin(), j_object2.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.210] iterators do not fit");
|
||||
EXPECT_THROW_MSG(j_object1.insert(j_array.begin(), j_array.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.202] iterators first and last must point to objects");
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, InitListBegin)
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin(), {7, 8, 9});
|
||||
EXPECT_EQ(j_array.size(), 7u);
|
||||
EXPECT_EQ(*it, json(7));
|
||||
EXPECT_EQ(j_array.begin(), it);
|
||||
EXPECT_EQ(j_array, json({7, 8, 9, 1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, InitListMiddle)
|
||||
{
|
||||
auto it = j_array.insert(j_array.begin() + 2, {7, 8, 9});
|
||||
EXPECT_EQ(j_array.size(), 7u);
|
||||
EXPECT_EQ(*it, json(7));
|
||||
EXPECT_EQ((it - j_array.begin()), 2);
|
||||
EXPECT_EQ(j_array, json({1, 2, 7, 8, 9, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, InitListEnd)
|
||||
{
|
||||
auto it = j_array.insert(j_array.end(), {7, 8, 9});
|
||||
EXPECT_EQ(j_array.size(), 7u);
|
||||
EXPECT_EQ(*it, json(7));
|
||||
EXPECT_EQ((j_array.end() - it), 3);
|
||||
EXPECT_EQ(j_array, json({1, 2, 3, 4, 7, 8, 9}));
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, InvalidIterator)
|
||||
{
|
||||
// pass iterator to a different array
|
||||
json j_another_array = {1, 2};
|
||||
json j_yet_another_array = {"first", "second"};
|
||||
EXPECT_THROW_MSG(j_array.insert(j_another_array.end(), 10), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.202] iterator does not fit current value");
|
||||
EXPECT_THROW_MSG(j_array.insert(j_another_array.end(), j_value), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.202] iterator does not fit current value");
|
||||
EXPECT_THROW_MSG(j_array.insert(j_another_array.end(), 10, 11), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.202] iterator does not fit current value");
|
||||
EXPECT_THROW_MSG(j_array.insert(j_another_array.end(), j_yet_another_array.begin(), j_yet_another_array.end()), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.202] iterator does not fit current value");
|
||||
EXPECT_THROW_MSG(j_array.insert(j_another_array.end(), {1, 2, 3, 4}), json::invalid_iterator,
|
||||
"[json.exception.invalid_iterator.202] iterator does not fit current value");
|
||||
}
|
||||
|
||||
TEST_F(JsonInsertTest, NonArray)
|
||||
{
|
||||
// call insert on a non-array type
|
||||
json j_nonarray = 3;
|
||||
json j_yet_another_array = {"first", "second"};
|
||||
EXPECT_THROW_MSG(j_nonarray.insert(j_nonarray.end(), 10), json::type_error,
|
||||
"[json.exception.type_error.309] cannot use insert() with number");
|
||||
EXPECT_THROW_MSG(j_nonarray.insert(j_nonarray.end(), j_value), json::type_error,
|
||||
"[json.exception.type_error.309] cannot use insert() with number");
|
||||
EXPECT_THROW_MSG(j_nonarray.insert(j_nonarray.end(), 10, 11), json::type_error,
|
||||
"[json.exception.type_error.309] cannot use insert() with number");
|
||||
EXPECT_THROW_MSG(j_nonarray.insert(j_nonarray.end(), j_yet_another_array.begin(),
|
||||
j_yet_another_array.end()), json::type_error,
|
||||
"[json.exception.type_error.309] cannot use insert() with number");
|
||||
EXPECT_THROW_MSG(j_nonarray.insert(j_nonarray.end(), {1, 2, 3, 4}), json::type_error,
|
||||
"[json.exception.type_error.309] cannot use insert() with number");
|
||||
}
|
||||
|
||||
TEST(JsonSwapTest, JsonMember)
|
||||
{
|
||||
json j("hello world");
|
||||
json k(42.23);
|
||||
|
||||
j.swap(k);
|
||||
|
||||
EXPECT_EQ(j, json(42.23));
|
||||
EXPECT_EQ(k, json("hello world"));
|
||||
}
|
||||
|
||||
TEST(JsonSwapTest, JsonNonMember)
|
||||
{
|
||||
json j("hello world");
|
||||
json k(42.23);
|
||||
|
||||
std::swap(j, k);
|
||||
|
||||
EXPECT_EQ(j, json(42.23));
|
||||
EXPECT_EQ(k, json("hello world"));
|
||||
}
|
||||
|
||||
TEST(JsonSwapTest, ArrayT)
|
||||
{
|
||||
json j = {1, 2, 3, 4};
|
||||
json::array_t a = {"foo", "bar", "baz"};
|
||||
|
||||
j.swap(a);
|
||||
|
||||
EXPECT_EQ(j, json({"foo", "bar", "baz"}));
|
||||
|
||||
j.swap(a);
|
||||
|
||||
EXPECT_EQ(j, json({1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
TEST(JsonSwapTest, NonArrayT)
|
||||
{
|
||||
json j = 17;
|
||||
json::array_t a = {"foo", "bar", "baz"};
|
||||
|
||||
EXPECT_THROW_MSG(j.swap(a), json::type_error,
|
||||
"[json.exception.type_error.310] cannot use swap() with number");
|
||||
}
|
||||
|
||||
TEST(JsonSwapTest, ObjectT)
|
||||
{
|
||||
json j = {{"one", 1}, {"two", 2}};
|
||||
json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}};
|
||||
|
||||
j.swap(o);
|
||||
|
||||
EXPECT_EQ(j, json({{"cow", "Kuh"}, {"chicken", "Huhn"}}));
|
||||
|
||||
j.swap(o);
|
||||
|
||||
EXPECT_EQ(j, json({{"one", 1}, {"two", 2}}));
|
||||
}
|
||||
|
||||
TEST(JsonSwapTest, NonObjectT)
|
||||
{
|
||||
json j = 17;
|
||||
json::object_t o = {{"cow", "Kuh"}, {"chicken", "Huhn"}};
|
||||
|
||||
EXPECT_THROW_MSG(j.swap(o), json::type_error,
|
||||
"[json.exception.type_error.310] cannot use swap() with number");
|
||||
}
|
||||
|
||||
TEST(JsonSwapTest, StringT)
|
||||
{
|
||||
json j = "Hello world";
|
||||
json::string_t s = "Hallo Welt";
|
||||
|
||||
j.swap(s);
|
||||
|
||||
EXPECT_EQ(j, json("Hallo Welt"));
|
||||
|
||||
j.swap(s);
|
||||
|
||||
EXPECT_EQ(j, json("Hello world"));
|
||||
}
|
||||
|
||||
TEST(JsonSwapTest, NonStringT)
|
||||
{
|
||||
json j = 17;
|
||||
json::string_t s = "Hallo Welt";
|
||||
|
||||
EXPECT_THROW_MSG(j.swap(s), json::type_error,
|
||||
"[json.exception.type_error.310] cannot use swap() with number");
|
||||
}
|
||||
1257
wpiutil/src/test/native/cpp/json/unit-msgpack.cpp
Normal file
1257
wpiutil/src/test/native/cpp/json/unit-msgpack.cpp
Normal file
File diff suppressed because it is too large
Load Diff
463
wpiutil/src/test/native/cpp/json/unit-pointer_access.cpp
Normal file
463
wpiutil/src/test/native/cpp/json/unit-pointer_access.cpp
Normal file
@@ -0,0 +1,463 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
TEST(JsonPointerTest, TypesCreate)
|
||||
{
|
||||
// create a JSON value with different types
|
||||
json json_types =
|
||||
{
|
||||
{"boolean", true},
|
||||
{
|
||||
"number", {
|
||||
{"integer", 42},
|
||||
{"unsigned", 42u},
|
||||
{"floating-point", 17.23}
|
||||
}
|
||||
},
|
||||
{"string", "Hello, world!"},
|
||||
{"array", {1, 2, 3, 4, 5}},
|
||||
{"null", nullptr}
|
||||
};
|
||||
}
|
||||
|
||||
// pointer access to object_t
|
||||
TEST(JsonPointerTest, ObjectT)
|
||||
{
|
||||
using test_type = json::object_t;
|
||||
json value = {{"one", 1}, {"two", 2}};
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_NE(value.get_ptr<json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::boolean_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to const object_t
|
||||
TEST(JsonPointerTest, ConstObjectT)
|
||||
{
|
||||
using test_type = const json::object_t;
|
||||
const json value = {{"one", 1}, {"two", 2}};
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_NE(value.get_ptr<const json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::boolean_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to array_t
|
||||
TEST(JsonPointerTest, ArrayT)
|
||||
{
|
||||
using test_type = json::array_t;
|
||||
json value = {1, 2, 3, 4};
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<json::object_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::boolean_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to const array_t
|
||||
TEST(JsonPointerTest, ConstArrayT)
|
||||
{
|
||||
using test_type = const json::array_t;
|
||||
const json value = {1, 2, 3, 4};
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<const json::object_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<const json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::boolean_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to string_t
|
||||
TEST(JsonPointerTest, StringT)
|
||||
{
|
||||
using test_type = json::string_t;
|
||||
json value = "hello";
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::array_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::boolean_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to const string_t
|
||||
TEST(JsonPointerTest, ConstStringT)
|
||||
{
|
||||
using test_type = const json::string_t;
|
||||
const json value = "hello";
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<const json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::array_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<const json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::boolean_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to boolean_t
|
||||
TEST(JsonPointerTest, BooleanT)
|
||||
{
|
||||
using test_type = json::boolean_t;
|
||||
json value = false;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::string_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<json::boolean_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to const boolean_t
|
||||
TEST(JsonPointerTest, ConstBooleanT)
|
||||
{
|
||||
using test_type = const json::boolean_t;
|
||||
const json value = false;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
//EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
//const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
//EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
//const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
//EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<const json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::string_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<const json::boolean_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to number_integer_t
|
||||
TEST(JsonPointerTest, IntegerT)
|
||||
{
|
||||
using test_type = json::number_integer_t;
|
||||
json value = 23;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::boolean_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to const number_integer_t
|
||||
TEST(JsonPointerTest, ConstIntegerT)
|
||||
{
|
||||
using test_type = const json::number_integer_t;
|
||||
const json value = 23;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<const json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::boolean_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<const json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to number_unsigned_t
|
||||
TEST(JsonPointerTest, UnsignedT)
|
||||
{
|
||||
using test_type = json::number_unsigned_t;
|
||||
json value = 23u;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::boolean_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<json::number_integer_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to const number_unsigned_t
|
||||
TEST(JsonPointerTest, ConstUnsignedT)
|
||||
{
|
||||
using test_type = const json::number_unsigned_t;
|
||||
const json value = 23u;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(*p1, value.get<test_type>());
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(*p2, value.get<test_type>());
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_EQ(*p3, value.get<test_type>());
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<const json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::boolean_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<const json::number_integer_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<const json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to number_float_t
|
||||
TEST(JsonPointerTest, FloatT)
|
||||
{
|
||||
using test_type = json::number_float_t;
|
||||
json value = 42.23;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_LT(std::fabs(*p1 - value.get<test_type>()), 0.001);
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_LT(std::fabs(*p2 - value.get<test_type>()), 0.001);
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_LT(std::fabs(*p3 - value.get<test_type>()), 0.001);
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::boolean_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<json::number_float_t*>(), nullptr);
|
||||
}
|
||||
|
||||
// pointer access to const number_float_t
|
||||
TEST(JsonPointerTest, ConstFloatT)
|
||||
{
|
||||
using test_type = const json::number_float_t;
|
||||
const json value = 42.23;
|
||||
|
||||
// check if pointers are returned correctly
|
||||
test_type* p1 = value.get_ptr<test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<test_type*>());
|
||||
EXPECT_LT(std::fabs(*p1 - value.get<test_type>()), 0.001);
|
||||
|
||||
const test_type* p2 = value.get_ptr<const test_type*>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type*>());
|
||||
EXPECT_LT(std::fabs(*p2 - value.get<test_type>()), 0.001);
|
||||
|
||||
const test_type* const p3 = value.get_ptr<const test_type* const>();
|
||||
EXPECT_EQ(p1, value.get_ptr<const test_type* const>());
|
||||
EXPECT_LT(std::fabs(*p3 - value.get<test_type>()), 0.001);
|
||||
|
||||
// check if null pointers are returned correctly
|
||||
EXPECT_EQ(value.get_ptr<const json::object_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::array_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::string_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::boolean_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_integer_t*>(), nullptr);
|
||||
EXPECT_EQ(value.get_ptr<const json::number_unsigned_t*>(), nullptr);
|
||||
EXPECT_NE(value.get_ptr<const json::number_float_t*>(), nullptr);
|
||||
}
|
||||
325
wpiutil/src/test/native/cpp/json/unit-readme.cpp
Normal file
325
wpiutil/src/test/native/cpp/json/unit-readme.cpp
Normal file
@@ -0,0 +1,325 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
#include <array>
|
||||
#include <deque>
|
||||
#include <forward_list>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
TEST(JsonReadmeTest, Basic)
|
||||
{
|
||||
// create an empty structure (null)
|
||||
json j;
|
||||
|
||||
// add a number that is stored as double (note the implicit conversion of j to an object)
|
||||
j["pi"] = 3.141;
|
||||
|
||||
// add a Boolean that is stored as bool
|
||||
j["happy"] = true;
|
||||
|
||||
// add a string that is stored as std::string
|
||||
j["name"] = "Niels";
|
||||
|
||||
// add another null object by passing nullptr
|
||||
j["nothing"] = nullptr;
|
||||
|
||||
// add an object inside the object
|
||||
j["answer"]["everything"] = 42;
|
||||
|
||||
// add an array that is stored as std::vector (using an initializer list)
|
||||
j["list"] = { 1, 0, 2 };
|
||||
|
||||
// add another object (using an initializer list of pairs)
|
||||
j["object"] = { {"currency", "USD"}, {"value", 42.99} };
|
||||
|
||||
// instead, you could also write (which looks very similar to the JSON above)
|
||||
json j2 =
|
||||
{
|
||||
{"pi", 3.141},
|
||||
{"happy", true},
|
||||
{"name", "Niels"},
|
||||
{"nothing", nullptr},
|
||||
{
|
||||
"answer", {
|
||||
{"everything", 42}
|
||||
}
|
||||
},
|
||||
{"list", {1, 0, 2}},
|
||||
{
|
||||
"object", {
|
||||
{"currency", "USD"},
|
||||
{"value", 42.99}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST(JsonReadmeTest, Other)
|
||||
{
|
||||
// ways to express the empty array []
|
||||
json empty_array_implicit = {{}};
|
||||
json empty_array_explicit = json::array();
|
||||
|
||||
// a way to express the empty object {}
|
||||
json empty_object_explicit = json::object();
|
||||
|
||||
// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
|
||||
json array_not_object = { json::array({"currency", "USD"}), json::array({"value", 42.99}) };
|
||||
}
|
||||
|
||||
TEST(JsonReadmeTest, FromToString)
|
||||
{
|
||||
// create object from string literal
|
||||
json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
|
||||
|
||||
// or even nicer with a raw string literal
|
||||
auto j2 = R"(
|
||||
{
|
||||
"happy": true,
|
||||
"pi": 3.141
|
||||
}
|
||||
)"_json;
|
||||
|
||||
// or explicitly
|
||||
auto j3 = json::parse("{ \"happy\": true, \"pi\": 3.141 }");
|
||||
|
||||
// explicit conversion to string
|
||||
std::string s;
|
||||
llvm::raw_string_ostream os(s);
|
||||
j.dump(os); // {\"happy\":true,\"pi\":3.141}
|
||||
EXPECT_EQ(os.str(), "{\"happy\":true,\"pi\":3.141}");
|
||||
|
||||
// serialization with pretty printing
|
||||
// pass in the amount of spaces to indent
|
||||
std::string s2;
|
||||
llvm::raw_string_ostream os2(s2);
|
||||
j2.dump(os2, 4);
|
||||
EXPECT_EQ(os2.str(), "{\n \"happy\": true,\n \"pi\": 3.141\n}");
|
||||
// {
|
||||
// "happy": true,
|
||||
// "pi": 3.141
|
||||
// }
|
||||
}
|
||||
|
||||
TEST(JsonReadmeTest, Basic2)
|
||||
{
|
||||
// create an array using push_back
|
||||
json j;
|
||||
j.push_back("foo");
|
||||
j.push_back(1);
|
||||
j.push_back(true);
|
||||
|
||||
std::string s;
|
||||
llvm::raw_string_ostream os(s);
|
||||
|
||||
// iterate the array
|
||||
for (json::iterator it = j.begin(); it != j.end(); ++it)
|
||||
{
|
||||
os << *it << '\n';
|
||||
}
|
||||
|
||||
// range-based for
|
||||
for (auto element : j)
|
||||
{
|
||||
os << element << '\n';
|
||||
}
|
||||
|
||||
// comparison
|
||||
bool x = (j == "[\"foo\", 1, true]"_json); // true
|
||||
EXPECT_EQ(x, true);
|
||||
|
||||
// getter/setter
|
||||
const std::string tmp = j[0];
|
||||
j[1] = 42;
|
||||
bool foo = j.at(2);
|
||||
EXPECT_EQ(foo, true);
|
||||
|
||||
// other stuff
|
||||
EXPECT_EQ(j.size(), 3u); // 3 entries
|
||||
EXPECT_EQ(j.empty(), false);
|
||||
EXPECT_EQ(j.type(), json::value_t::array);
|
||||
j.clear(); // the array is empty again
|
||||
EXPECT_EQ(j.size(), 0u);
|
||||
EXPECT_EQ(j.empty(), true);
|
||||
|
||||
// create an object
|
||||
json o;
|
||||
o["foo"] = 23;
|
||||
o["bar"] = false;
|
||||
o["baz"] = 3.141;
|
||||
|
||||
// find an entry
|
||||
if (o.find("foo") != o.end())
|
||||
{
|
||||
// there is an entry with key "foo"
|
||||
}
|
||||
}
|
||||
|
||||
TEST(JsonReadmeTest, OtherContainer)
|
||||
{
|
||||
std::vector<int> c_vector {1, 2, 3, 4};
|
||||
json j_vec(c_vector);
|
||||
json j_vec2(llvm::makeArrayRef(c_vector));
|
||||
// [1, 2, 3, 4]
|
||||
|
||||
std::deque<float> c_deque {1.2f, 2.3f, 3.4f, 5.6f};
|
||||
json j_deque(c_deque);
|
||||
// [1.2, 2.3, 3.4, 5.6]
|
||||
|
||||
std::list<bool> c_list {true, true, false, true};
|
||||
json j_list(c_list);
|
||||
// [true, true, false, true]
|
||||
|
||||
std::forward_list<int64_t> c_flist {12345678909876, 23456789098765, 34567890987654, 45678909876543};
|
||||
json j_flist(c_flist);
|
||||
// [12345678909876, 23456789098765, 34567890987654, 45678909876543]
|
||||
|
||||
std::array<unsigned long, 4> c_array {{1, 2, 3, 4}};
|
||||
json j_array(c_array);
|
||||
// [1, 2, 3, 4]
|
||||
|
||||
std::set<std::string> c_set {"one", "two", "three", "four", "one"};
|
||||
json j_set(c_set); // only one entry for "one" is used
|
||||
// ["four", "one", "three", "two"]
|
||||
|
||||
std::unordered_set<std::string> c_uset {"one", "two", "three", "four", "one"};
|
||||
json j_uset(c_uset); // only one entry for "one" is used
|
||||
// maybe ["two", "three", "four", "one"]
|
||||
|
||||
std::multiset<std::string> c_mset {"one", "two", "one", "four"};
|
||||
json j_mset(c_mset); // both entries for "one" are used
|
||||
// maybe ["one", "two", "one", "four"]
|
||||
|
||||
std::unordered_multiset<std::string> c_umset {"one", "two", "one", "four"};
|
||||
json j_umset(c_umset); // both entries for "one" are used
|
||||
// maybe ["one", "two", "one", "four"]
|
||||
}
|
||||
|
||||
TEST(JsonReadmeTest, MapContainer)
|
||||
{
|
||||
std::map<std::string, int> c_map { {"one", 1}, {"two", 2}, {"three", 3} };
|
||||
json j_map(c_map);
|
||||
// {"one": 1, "two": 2, "three": 3}
|
||||
|
||||
#if 0
|
||||
std::unordered_map<const char*, float> c_umap { {"one", 1.2f}, {"two", 2.3f}, {"three", 3.4f} };
|
||||
json j_umap(c_umap);
|
||||
// {"one": 1.2, "two": 2.3, "three": 3.4}
|
||||
#endif
|
||||
|
||||
std::multimap<std::string, bool> c_mmap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
|
||||
json j_mmap(c_mmap); // only one entry for key "three" is used
|
||||
// maybe {"one": true, "two": true, "three": true}
|
||||
|
||||
std::unordered_multimap<std::string, bool> c_ummap { {"one", true}, {"two", true}, {"three", false}, {"three", true} };
|
||||
json j_ummap(c_ummap); // only one entry for key "three" is used
|
||||
// maybe {"one": true, "two": true, "three": true}
|
||||
}
|
||||
|
||||
TEST(JsonReadmeTest, Values)
|
||||
{
|
||||
// strings
|
||||
std::string s1 = "Hello, world!";
|
||||
json js = s1;
|
||||
std::string s2 = js;
|
||||
EXPECT_EQ(s1, s2);
|
||||
|
||||
// Booleans
|
||||
bool b1 = true;
|
||||
json jb = b1;
|
||||
bool b2 = jb;
|
||||
EXPECT_EQ(b1, b2);
|
||||
|
||||
// numbers
|
||||
int i = 42;
|
||||
json jn = i;
|
||||
double f = jn;
|
||||
EXPECT_EQ(i, f);
|
||||
|
||||
// etc.
|
||||
|
||||
std::string vs = js.get<std::string>();
|
||||
bool vb = jb.get<bool>();
|
||||
int vi = jn.get<int>();
|
||||
EXPECT_EQ(s1, vs);
|
||||
EXPECT_EQ(b1, vb);
|
||||
EXPECT_EQ(i, vi);
|
||||
|
||||
// etc.
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(JsonReadmeTest, DiffPatch)
|
||||
{
|
||||
// a JSON value
|
||||
json j_original = R"({
|
||||
"baz": ["one", "two", "three"],
|
||||
"foo": "bar"
|
||||
})"_json;
|
||||
|
||||
// access members with a JSON pointer (RFC 6901)
|
||||
j_original["/baz/1"_json_pointer];
|
||||
// "two"
|
||||
|
||||
// a JSON patch (RFC 6902)
|
||||
json j_patch = R"([
|
||||
{ "op": "replace", "path": "/baz", "value": "boo" },
|
||||
{ "op": "add", "path": "/hello", "value": ["world"] },
|
||||
{ "op": "remove", "path": "/foo"}
|
||||
])"_json;
|
||||
|
||||
// apply the patch
|
||||
json j_result = j_original.patch(j_patch);
|
||||
// {
|
||||
// "baz": "boo",
|
||||
// "hello": ["world"]
|
||||
// }
|
||||
|
||||
// calculate a JSON patch from two JSON values
|
||||
json::diff(j_result, j_original);
|
||||
// [
|
||||
// { "op":" replace", "path": "/baz", "value": ["one", "two", "three"] },
|
||||
// { "op":"remove","path":"/hello" },
|
||||
// { "op":"add","path":"/foo","value":"bar" }
|
||||
// ]
|
||||
}
|
||||
#endif
|
||||
197
wpiutil/src/test/native/cpp/json/unit-reference_access.cpp
Normal file
197
wpiutil/src/test/native/cpp/json/unit-reference_access.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Modifications Copyright (c) FIRST 2017. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++ (test suite)
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "unit-json.h"
|
||||
using wpi::json;
|
||||
|
||||
// reference access to object_t
|
||||
TEST(JsonReferenceTest, ObjectT)
|
||||
{
|
||||
using test_type = json::object_t;
|
||||
json value = {{"one", 1}, {"two", 2}};
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
EXPECT_EQ(&p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(p1, value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
EXPECT_EQ(&p2, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(p2, value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
EXPECT_NO_THROW(value.get_ref<json::object_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::array_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::string_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::boolean_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::number_integer_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::number_float_t&>());
|
||||
}
|
||||
|
||||
// const reference access to const object_t
|
||||
TEST(JsonReferenceTest, ConstObjectT)
|
||||
{
|
||||
using test_type = json::object_t;
|
||||
const json value = {{"one", 1}, {"two", 2}};
|
||||
|
||||
// this should not compile
|
||||
// test_type& p1 = value.get_ref<test_type&>();
|
||||
|
||||
// check if references are returned correctly
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
EXPECT_EQ(&p2, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(p2, value.get<test_type>());
|
||||
}
|
||||
|
||||
// reference access to array_t
|
||||
TEST(JsonReferenceTest, ArrayT)
|
||||
{
|
||||
using test_type = json::array_t;
|
||||
json value = {1, 2, 3, 4};
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
EXPECT_EQ(&p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(p1, value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
EXPECT_EQ(&p2, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(p2, value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
EXPECT_ANY_THROW(value.get_ref<json::object_t&>());
|
||||
EXPECT_NO_THROW(value.get_ref<json::array_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::string_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::boolean_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::number_integer_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::number_float_t&>());
|
||||
}
|
||||
|
||||
// reference access to string_t
|
||||
TEST(JsonReferenceTest, StringT)
|
||||
{
|
||||
using test_type = json::string_t;
|
||||
json value = "hello";
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
EXPECT_EQ(&p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(p1, value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
EXPECT_EQ(&p2, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(p2, value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
EXPECT_ANY_THROW(value.get_ref<json::object_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::array_t&>());
|
||||
EXPECT_NO_THROW(value.get_ref<json::string_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::boolean_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::number_integer_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::number_float_t&>());
|
||||
}
|
||||
|
||||
// reference access to boolean_t
|
||||
TEST(JsonReferenceTest, BooleanT)
|
||||
{
|
||||
using test_type = json::boolean_t;
|
||||
json value = false;
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
EXPECT_EQ(&p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(p1, value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
EXPECT_EQ(&p2, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(p2, value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
EXPECT_ANY_THROW(value.get_ref<json::object_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::array_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::string_t&>());
|
||||
EXPECT_NO_THROW(value.get_ref<json::boolean_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::number_integer_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::number_float_t&>());
|
||||
}
|
||||
|
||||
// reference access to number_integer_t
|
||||
TEST(JsonReferenceTest, IntegerT)
|
||||
{
|
||||
using test_type = json::number_integer_t;
|
||||
json value = 23;
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
EXPECT_EQ(&p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(p1, value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
EXPECT_EQ(&p2, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(p2, value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
EXPECT_ANY_THROW(value.get_ref<json::object_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::array_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::string_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::boolean_t&>());
|
||||
EXPECT_NO_THROW(value.get_ref<json::number_integer_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::number_float_t&>());
|
||||
}
|
||||
|
||||
// reference access to number_float_t
|
||||
TEST(JsonReferenceTest, FloatT)
|
||||
{
|
||||
using test_type = json::number_float_t;
|
||||
json value = 42.23;
|
||||
|
||||
// check if references are returned correctly
|
||||
test_type& p1 = value.get_ref<test_type&>();
|
||||
EXPECT_EQ(&p1, value.get_ptr<test_type*>());
|
||||
EXPECT_EQ(p1, value.get<test_type>());
|
||||
|
||||
const test_type& p2 = value.get_ref<const test_type&>();
|
||||
EXPECT_EQ(&p2, value.get_ptr<const test_type*>());
|
||||
EXPECT_EQ(p2, value.get<test_type>());
|
||||
|
||||
// check if mismatching references throw correctly
|
||||
EXPECT_ANY_THROW(value.get_ref<json::object_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::array_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::string_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::boolean_t&>());
|
||||
EXPECT_ANY_THROW(value.get_ref<json::number_integer_t&>());
|
||||
EXPECT_NO_THROW(value.get_ref<json::number_float_t&>());
|
||||
}
|
||||
1092
wpiutil/src/test/native/cpp/json/unit-unicode.cpp
Normal file
1092
wpiutil/src/test/native/cpp/json/unit-unicode.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user