221 lines
4.8 KiB
C++
221 lines
4.8 KiB
C++
|
//
|
||
|
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
|
||
|
// Copyright (c) 2022 Dmitry Arkhipov (grisumbras@yandex.ru)
|
||
|
//
|
||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||
|
//
|
||
|
// Official repository: https://github.com/boostorg/json
|
||
|
//
|
||
|
|
||
|
// Test that header file is self-contained.
|
||
|
#include <boost/json/parse.hpp>
|
||
|
|
||
|
#include <boost/json/serialize.hpp>
|
||
|
|
||
|
#include <string>
|
||
|
|
||
|
#include "test.hpp"
|
||
|
#include "test_suite.hpp"
|
||
|
|
||
|
namespace boost {
|
||
|
namespace json {
|
||
|
|
||
|
class parse_test
|
||
|
{
|
||
|
public:
|
||
|
bool hasLocation(std::error_code const&)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool hasLocation(error_code const& ec)
|
||
|
{
|
||
|
return ec.has_location();
|
||
|
}
|
||
|
|
||
|
template <class ErrorCode>
|
||
|
void
|
||
|
good_impl(string_view s)
|
||
|
{
|
||
|
ErrorCode ec;
|
||
|
auto jv = parse(s, ec);
|
||
|
if(! BOOST_TEST(! ec))
|
||
|
return;
|
||
|
BOOST_TEST(
|
||
|
serialize(jv) == s);
|
||
|
|
||
|
std::stringstream ss(s);
|
||
|
auto jv2 = parse(ss, ec);
|
||
|
if(! BOOST_TEST(! ec))
|
||
|
return;
|
||
|
BOOST_TEST( jv == jv2 );
|
||
|
}
|
||
|
|
||
|
template <class ErrorCode>
|
||
|
void
|
||
|
bad_impl(string_view s)
|
||
|
{
|
||
|
ErrorCode ec;
|
||
|
auto jv = parse(s, ec);
|
||
|
BOOST_TEST(ec);
|
||
|
BOOST_TEST(hasLocation(ec));
|
||
|
|
||
|
ec = {};
|
||
|
std::stringstream ss(s);
|
||
|
auto jv2 = parse(ss, ec);
|
||
|
BOOST_TEST(ec);
|
||
|
BOOST_TEST(hasLocation(ec));
|
||
|
}
|
||
|
|
||
|
void
|
||
|
good(string_view s)
|
||
|
{
|
||
|
good_impl<error_code>(s);
|
||
|
good_impl<std::error_code>(s);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
bad(string_view s)
|
||
|
{
|
||
|
bad_impl<error_code>(s);
|
||
|
bad_impl<std::error_code>(s);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
testParse()
|
||
|
{
|
||
|
good("null");
|
||
|
good("[1,2,3]");
|
||
|
good("17");
|
||
|
bad ("[1,2,3] #");
|
||
|
bad ("555415214748364655415E2147483646");
|
||
|
bad ("9.88874836020e-2147483640");
|
||
|
}
|
||
|
|
||
|
void
|
||
|
testMemoryUsage()
|
||
|
{
|
||
|
// string
|
||
|
{
|
||
|
std::string s(10000, '*');
|
||
|
s.insert(s.begin(), '\"');
|
||
|
s.append(1, '\"');
|
||
|
|
||
|
fail_resource mr1;
|
||
|
value jv1 = parse(s, &mr1);
|
||
|
|
||
|
fail_resource mr2;
|
||
|
value jv2(jv1, &mr2);
|
||
|
BOOST_TEST(mr1.bytes == mr2.bytes);
|
||
|
|
||
|
fail_resource mr3;
|
||
|
value jv3(&mr3);
|
||
|
jv3 = jv1;
|
||
|
BOOST_TEST(mr1.bytes == mr3.bytes);
|
||
|
}
|
||
|
|
||
|
// array
|
||
|
{
|
||
|
{
|
||
|
fail_resource mr1;
|
||
|
value jv1 = parse("[1]", &mr1);
|
||
|
|
||
|
fail_resource mr2;
|
||
|
value jv2(jv1, &mr2);
|
||
|
BOOST_TEST(mr1.bytes == mr2.bytes);
|
||
|
|
||
|
fail_resource mr3;
|
||
|
value jv3(&mr3);
|
||
|
jv3 = jv1;
|
||
|
BOOST_TEST(mr1.bytes == mr3.bytes);
|
||
|
}
|
||
|
{
|
||
|
std::string s;
|
||
|
s = "1,2,3,4";
|
||
|
s = s + "," + s;
|
||
|
s = s + "," + s;
|
||
|
s = s + "," + s;
|
||
|
s = s + "," + s;
|
||
|
s = s + "," + s;
|
||
|
s = s + "," + s;
|
||
|
s = s + "," + s;
|
||
|
s = s + "," + s;
|
||
|
s = "[[" + s + "]]";
|
||
|
|
||
|
fail_resource mr1;
|
||
|
value jv1 = parse(s, &mr1);
|
||
|
|
||
|
fail_resource mr2;
|
||
|
value jv2(jv1, &mr2);
|
||
|
BOOST_TEST(mr1.bytes == mr2.bytes);
|
||
|
|
||
|
fail_resource mr3;
|
||
|
value jv3(&mr3);
|
||
|
jv3 = jv1;
|
||
|
BOOST_TEST(mr1.bytes == mr3.bytes);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// object
|
||
|
{
|
||
|
std::string s;
|
||
|
s = "{\"0\":null";
|
||
|
for(int i = 1; i < 1000; ++i)
|
||
|
s +=
|
||
|
",\"" +
|
||
|
std::to_string(i) +
|
||
|
"\":null";
|
||
|
s.append("}");
|
||
|
|
||
|
fail_resource mr1;
|
||
|
value jv1 = parse(s, &mr1);
|
||
|
|
||
|
fail_resource mr2;
|
||
|
value jv2(jv1, &mr2);
|
||
|
BOOST_TEST(mr1.bytes == mr2.bytes);
|
||
|
|
||
|
fail_resource mr3;
|
||
|
value jv3(&mr3);
|
||
|
jv3 = jv1;
|
||
|
BOOST_TEST(mr1.bytes == mr3.bytes);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
testIssue726()
|
||
|
{
|
||
|
parse_options opt;
|
||
|
opt.allow_comments = true;
|
||
|
opt.allow_trailing_commas = true;
|
||
|
char const* text1 = "[ 123, //\n]";
|
||
|
value arr = parse(text1, {}, opt);
|
||
|
BOOST_TEST(arr == array{123});
|
||
|
}
|
||
|
|
||
|
void
|
||
|
testIstream()
|
||
|
{
|
||
|
std::stringstream ss("null");
|
||
|
parse(ss); // does not throw
|
||
|
|
||
|
ss.clear();
|
||
|
ss.setstate(std::ios::failbit);
|
||
|
BOOST_TEST_THROWS( parse(ss), system_error );
|
||
|
}
|
||
|
|
||
|
void
|
||
|
run()
|
||
|
{
|
||
|
testParse();
|
||
|
testMemoryUsage();
|
||
|
testIssue726();
|
||
|
testIstream();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
TEST_SUITE(parse_test, "boost.json.parse");
|
||
|
|
||
|
} // namespace json
|
||
|
} // namespace boost
|