]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/json/test/pointer.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / json / test / pointer.cpp
CommitLineData
1e59de90
TL
1//
2// Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com)
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// Official repository: https://github.com/boostorg/json
8//
9
10#include <boost/json/value.hpp>
11
12#include "test_suite.hpp"
13
14BOOST_JSON_NS_BEGIN
15
16
17class pointer_test
18{
19 bool
20 hasLocation(error_code const& ec)
21 {
22 return ec.has_location();
23 }
24
25 bool
26 hasLocation(std::error_code const&)
27 {
28 return true;
29 }
30
31 value
32 testValue() const
33 {
34 return value{
35 {"foo", {"bar", "baz", "baf"}},
36 {"", 0},
37 {"a/b", 1},
38 {"c%d", 2},
39 {"e^f", 3},
40 {"g|h", 4},
41 {"i\\j", 5},
42 {"k\"l", 6},
43 {" ", 7},
44 {"m~n", 8},
45 {"x", object{{"y", "z"}}},
46 };
47 }
48
49 value
50 bigObject() const
51 {
52 object result;
53 for (int i = 0; i < 50; ++i)
54 {
55 result.emplace(std::to_string(i), i);
56 }
57 return result;
58 }
59
60public:
61 void
62 testRootPointer()
63 {
64 value const jv = testValue();
65 BOOST_TEST(&jv.at_pointer("") == &jv);
66 }
67
68 void
69 testChildPointer()
70 {
71 value const jv = testValue();
72 BOOST_TEST(&jv.at_pointer("/foo")== &jv.at("foo"));
73 BOOST_TEST(&jv.at_pointer("/c%d")== &jv.at("c%d"));
74 BOOST_TEST(&jv.at_pointer("/e^f")== &jv.at("e^f"));
75 BOOST_TEST(&jv.at_pointer("/g|h")== &jv.at("g|h"));
76 BOOST_TEST(&jv.at_pointer("/")== &jv.at(""));
77 BOOST_TEST(&jv.at_pointer("/i\\j")== &jv.at("i\\j"));
78 BOOST_TEST(&jv.at_pointer("/k\"l")== &jv.at("k\"l"));
79 BOOST_TEST(&jv.at_pointer("/ ")== &jv.at(" "));
80 }
81
82 void
83 testEscaped()
84 {
85 value const jv = testValue();
86 BOOST_TEST(&jv.at_pointer("/a~1b")== &jv.at("a/b"));
87 BOOST_TEST(&jv.at_pointer("/m~0n")== &jv.at("m~n"));
88 }
89
90 void
91 testNested()
92 {
93 value const jv = testValue();
94 BOOST_TEST(&jv.at_pointer("/foo/0") == &jv.at("foo").at(0));
95 BOOST_TEST(&jv.at_pointer("/foo/1") == &jv.at("foo").at(1));
96 BOOST_TEST(&jv.at_pointer("/x/y") == &jv.at("x").at("y"));
97
98 {
99 value v1;
100 object& o1 = v1.emplace_object();
101 object& o2 = (o1["very"] = value()).emplace_object();
102 object& o3 = (o2["deep"] = value()).emplace_object();
103
104 array& a1 = (o3["path"] = value()).emplace_array();
105 a1.emplace_back(value());
106
107 array& a2 = a1.emplace_back(value()).emplace_array();
108 a2.emplace_back(value());
109 a2.emplace_back(value());
110
111 array& a3 = a2.emplace_back(value()).emplace_array();
112 object& o4 = a3.emplace_back(value()).emplace_object();
113 object& o5 = (o4["0"] = value()).emplace_object();
114 value& v2 = o5["fin"] = value();
115
116 BOOST_TEST(&v1.at_pointer("/very/deep/path/1/2/0/0/fin") == &v2);
117 }
118 }
119
120 void
121 testErrors()
122 {
123 value const jv = testValue();
124 BOOST_TEST_THROWS(jv.at_pointer("foo"), system_error);
125 BOOST_TEST_THROWS(jv.at_pointer("/fo"), system_error);
126 BOOST_TEST_THROWS(jv.at_pointer("/m~"), system_error);
127 BOOST_TEST_THROWS(jv.at_pointer("/m~n"), system_error);
128 BOOST_TEST_THROWS(jv.at_pointer("/foo/bar"), system_error);
129 BOOST_TEST_THROWS(jv.at_pointer("/foo/"), system_error);
130 BOOST_TEST_THROWS(jv.at_pointer("/foo/01"), system_error);
131 BOOST_TEST_THROWS(jv.at_pointer("/foo/2b"), system_error);
132 BOOST_TEST_THROWS(jv.at_pointer("/x/y/z"), system_error);
133 }
134
135 template<class ErrorCode>
136 void
137 testNonThrowing()
138 {
139 value jv = testValue();
140 ErrorCode ec = error::syntax;
141 BOOST_TEST(jv.find_pointer("/foo/0", ec) == &jv.at("foo").at(0));
142 BOOST_TEST(!ec);
143
144 auto const& cjv = jv;
145 ec = error::syntax;
146 BOOST_TEST(cjv.find_pointer("/foo/1", ec) == &jv.at("foo").at(1));
147 BOOST_TEST(!ec);
148
149 jv.find_pointer("foo", ec);
150 BOOST_TEST(ec == error::missing_slash);
151 BOOST_TEST(hasLocation(ec));
152
153 jv.find_pointer("/fo", ec);
154 BOOST_TEST(ec == error::not_found);
155 BOOST_TEST(hasLocation(ec));
156
157 jv.find_pointer("/foo/25", ec);
158 BOOST_TEST(ec == error::not_found);
159 BOOST_TEST(hasLocation(ec));
160
161 value(object()).find_pointer("/foo", ec);
162 BOOST_TEST(ec == error::not_found);
163 BOOST_TEST(hasLocation(ec));
164
165 bigObject().find_pointer("/foo", ec);
166 BOOST_TEST(ec == error::not_found);
167 BOOST_TEST(hasLocation(ec));
168
169 jv.find_pointer("/m~", ec);
170 BOOST_TEST(ec == error::invalid_escape);
171 BOOST_TEST(hasLocation(ec));
172
173 jv.find_pointer("/m~n", ec);
174 BOOST_TEST(ec == error::invalid_escape);
175 BOOST_TEST(hasLocation(ec));
176
177 jv.find_pointer("/foo/bar", ec);
178 BOOST_TEST(ec == error::token_not_number);
179 BOOST_TEST(hasLocation(ec));
180
181 jv.find_pointer("/foo/", ec);
182 BOOST_TEST(ec == error::token_not_number);
183 BOOST_TEST(hasLocation(ec));
184
185 jv.find_pointer("/foo/01", ec);
186 BOOST_TEST(ec == error::token_not_number);
187 BOOST_TEST(hasLocation(ec));
188
189 jv.find_pointer("/foo/2b", ec);
190 BOOST_TEST(ec == error::token_not_number);
191 BOOST_TEST(hasLocation(ec));
192
193 jv.find_pointer("/foo/2.", ec);
194 BOOST_TEST(ec == error::token_not_number);
195 BOOST_TEST(hasLocation(ec));
196
197 jv.find_pointer("/foo/-", ec);
198 BOOST_TEST(ec == error::past_the_end);
199 BOOST_TEST(hasLocation(ec));
200
201 jv.find_pointer("/foo/-/x", ec);
202 BOOST_TEST(ec == error::past_the_end);
203 BOOST_TEST(hasLocation(ec));
204
205 jv.find_pointer("/foo/-1", ec);
206 BOOST_TEST(ec == error::token_not_number);
207 BOOST_TEST(hasLocation(ec));
208
209 jv.find_pointer("/x/y/z", ec);
210 BOOST_TEST(ec == error::value_is_scalar);
211 BOOST_TEST(hasLocation(ec));
212
213 string s = "/foo/";
214 s += std::to_string((std::numeric_limits<std::size_t>::max)());
215 if ( '9' == s[s.size() - 1] )
216 {
217 for (std::size_t i = 6; i < s.size(); ++i)
218 {
219 s[i] = '0';
220 }
221 s[5] = '1';
222 s += "0";
223 }
224 else
225 {
226 ++s[s.size() - 1];
227 }
228 jv.find_pointer(s, ec);
229 BOOST_TEST(ec == error::token_overflow);
230 BOOST_TEST(hasLocation(ec));
231 }
232
233 void
234 run()
235 {
236 testRootPointer();
237 testChildPointer();
238 testEscaped();
239 testNested();
240 testErrors();
241 testNonThrowing<error_code>();
242 testNonThrowing<std::error_code>();
243 }
244};
245
246TEST_SUITE(pointer_test, "boost.json.pointer");
247
248BOOST_JSON_NS_END