rj_schema 1.0.0 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/rj_schema/rapidjson/CMakeLists.txt +23 -1
- data/ext/rj_schema/rapidjson/appveyor.yml +49 -1
- data/ext/rj_schema/rapidjson/bin/types/alotofkeys.json +502 -0
- data/ext/rj_schema/rapidjson/bin/unittestschema/idandref.json +69 -0
- data/ext/rj_schema/rapidjson/doc/stream.md +7 -7
- data/ext/rj_schema/rapidjson/doc/stream.zh-cn.md +1 -1
- data/ext/rj_schema/rapidjson/doc/tutorial.md +15 -15
- data/ext/rj_schema/rapidjson/example/schemavalidator/schemavalidator.cpp +2 -0
- data/ext/rj_schema/rapidjson/example/traverseaspointer.cpp +39 -0
- data/ext/rj_schema/rapidjson/include/rapidjson/allocators.h +460 -52
- data/ext/rj_schema/rapidjson/include/rapidjson/document.h +350 -60
- data/ext/rj_schema/rapidjson/include/rapidjson/internal/strfunc.h +14 -0
- data/ext/rj_schema/rapidjson/include/rapidjson/pointer.h +68 -1
- data/ext/rj_schema/rapidjson/include/rapidjson/rapidjson.h +60 -11
- data/ext/rj_schema/rapidjson/include/rapidjson/schema.h +249 -102
- data/ext/rj_schema/rapidjson/include/rapidjson/uri.h +466 -0
- data/ext/rj_schema/rapidjson/test/perftest/perftest.h +5 -4
- data/ext/rj_schema/rapidjson/test/perftest/rapidjsontest.cpp +20 -2
- data/ext/rj_schema/rapidjson/test/unittest/CMakeLists.txt +2 -0
- data/ext/rj_schema/rapidjson/test/unittest/allocatorstest.cpp +193 -1
- data/ext/rj_schema/rapidjson/test/unittest/documenttest.cpp +2 -0
- data/ext/rj_schema/rapidjson/test/unittest/platformtest.cpp +40 -0
- data/ext/rj_schema/rapidjson/test/unittest/pointertest.cpp +62 -2
- data/ext/rj_schema/rapidjson/test/unittest/schematest.cpp +372 -7
- data/ext/rj_schema/rapidjson/test/unittest/uritest.cpp +718 -0
- data/ext/rj_schema/rapidjson/test/unittest/valuetest.cpp +12 -2
- data/ext/rj_schema/rj_schema.cpp +3 -10
- data/lib/rj_schema.rb +1 -1
- metadata +9 -3
@@ -16,6 +16,11 @@
|
|
16
16
|
|
17
17
|
#include "rapidjson/allocators.h"
|
18
18
|
|
19
|
+
#include <map>
|
20
|
+
#include <string>
|
21
|
+
#include <utility>
|
22
|
+
#include <functional>
|
23
|
+
|
19
24
|
using namespace rapidjson;
|
20
25
|
|
21
26
|
template <typename Allocator>
|
@@ -47,19 +52,206 @@ void TestAllocator(Allocator& a) {
|
|
47
52
|
EXPECT_TRUE(a.Realloc(a.Malloc(1), 1, 0) == 0);
|
48
53
|
}
|
49
54
|
|
55
|
+
struct TestStdAllocatorData {
|
56
|
+
TestStdAllocatorData(int &constructions, int &destructions) :
|
57
|
+
constructions_(&constructions),
|
58
|
+
destructions_(&destructions)
|
59
|
+
{
|
60
|
+
++*constructions_;
|
61
|
+
}
|
62
|
+
TestStdAllocatorData(const TestStdAllocatorData& rhs) :
|
63
|
+
constructions_(rhs.constructions_),
|
64
|
+
destructions_(rhs.destructions_)
|
65
|
+
{
|
66
|
+
++*constructions_;
|
67
|
+
}
|
68
|
+
TestStdAllocatorData& operator=(const TestStdAllocatorData& rhs)
|
69
|
+
{
|
70
|
+
this->~TestStdAllocatorData();
|
71
|
+
constructions_ = rhs.constructions_;
|
72
|
+
destructions_ = rhs.destructions_;
|
73
|
+
++*constructions_;
|
74
|
+
return *this;
|
75
|
+
}
|
76
|
+
~TestStdAllocatorData()
|
77
|
+
{
|
78
|
+
++*destructions_;
|
79
|
+
}
|
80
|
+
private:
|
81
|
+
TestStdAllocatorData();
|
82
|
+
int *constructions_,
|
83
|
+
*destructions_;
|
84
|
+
};
|
85
|
+
|
86
|
+
template <typename Allocator>
|
87
|
+
void TestStdAllocator(const Allocator& a) {
|
88
|
+
#if RAPIDJSON_HAS_CXX17
|
89
|
+
typedef StdAllocator<bool, Allocator> BoolAllocator;
|
90
|
+
#else
|
91
|
+
typedef StdAllocator<void, Allocator> VoidAllocator;
|
92
|
+
typedef typename VoidAllocator::template rebind<bool>::other BoolAllocator;
|
93
|
+
#endif
|
94
|
+
BoolAllocator ba(a), ba2(a);
|
95
|
+
EXPECT_TRUE(ba == ba2);
|
96
|
+
EXPECT_FALSE(ba!= ba2);
|
97
|
+
ba.deallocate(ba.allocate());
|
98
|
+
EXPECT_TRUE(ba == ba2);
|
99
|
+
EXPECT_FALSE(ba != ba2);
|
100
|
+
|
101
|
+
unsigned long long ll = 0, *llp = ≪
|
102
|
+
const unsigned long long cll = 0, *cllp = &cll;
|
103
|
+
StdAllocator<unsigned long long, Allocator> lla(a);
|
104
|
+
EXPECT_EQ(lla.address(ll), llp);
|
105
|
+
EXPECT_EQ(lla.address(cll), cllp);
|
106
|
+
EXPECT_TRUE(lla.max_size() > 0 && lla.max_size() <= SIZE_MAX / sizeof(unsigned long long));
|
107
|
+
|
108
|
+
int *arr;
|
109
|
+
StdAllocator<int, Allocator> ia(a);
|
110
|
+
arr = ia.allocate(10 * sizeof(int));
|
111
|
+
EXPECT_TRUE(arr != 0);
|
112
|
+
for (int i = 0; i < 10; ++i) {
|
113
|
+
arr[i] = 0x0f0f0f0f;
|
114
|
+
}
|
115
|
+
ia.deallocate(arr, 10);
|
116
|
+
arr = Malloc<int>(ia, 10);
|
117
|
+
EXPECT_TRUE(arr != 0);
|
118
|
+
for (int i = 0; i < 10; ++i) {
|
119
|
+
arr[i] = 0x0f0f0f0f;
|
120
|
+
}
|
121
|
+
arr = Realloc<int>(ia, arr, 10, 20);
|
122
|
+
EXPECT_TRUE(arr != 0);
|
123
|
+
for (int i = 0; i < 10; ++i) {
|
124
|
+
EXPECT_EQ(arr[i], 0x0f0f0f0f);
|
125
|
+
}
|
126
|
+
for (int i = 10; i < 20; i++) {
|
127
|
+
arr[i] = 0x0f0f0f0f;
|
128
|
+
}
|
129
|
+
Free<int>(ia, arr, 20);
|
130
|
+
|
131
|
+
int cons = 0, dest = 0;
|
132
|
+
StdAllocator<TestStdAllocatorData, Allocator> da(a);
|
133
|
+
for (int i = 1; i < 10; i++) {
|
134
|
+
TestStdAllocatorData *d = da.allocate();
|
135
|
+
EXPECT_TRUE(d != 0);
|
136
|
+
|
137
|
+
da.destroy(new(d) TestStdAllocatorData(cons, dest));
|
138
|
+
EXPECT_EQ(cons, i);
|
139
|
+
EXPECT_EQ(dest, i);
|
140
|
+
|
141
|
+
da.deallocate(d);
|
142
|
+
}
|
143
|
+
|
144
|
+
typedef StdAllocator<char, Allocator> CharAllocator;
|
145
|
+
typedef std::basic_string<char, std::char_traits<char>, CharAllocator> String;
|
146
|
+
#if RAPIDJSON_HAS_CXX11
|
147
|
+
String s(CharAllocator{a});
|
148
|
+
#else
|
149
|
+
CharAllocator ca(a);
|
150
|
+
String s(ca);
|
151
|
+
#endif
|
152
|
+
for (int i = 0; i < 26; i++) {
|
153
|
+
s.push_back(static_cast<char>('A' + i));
|
154
|
+
}
|
155
|
+
EXPECT_TRUE(s == "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
156
|
+
|
157
|
+
typedef StdAllocator<std::pair<const int, bool>, Allocator> MapAllocator;
|
158
|
+
typedef std::map<int, bool, std::less<int>, MapAllocator> Map;
|
159
|
+
#if RAPIDJSON_HAS_CXX11
|
160
|
+
Map map(std::less<int>(), MapAllocator{a});
|
161
|
+
#else
|
162
|
+
MapAllocator ma(a);
|
163
|
+
Map map(std::less<int>(), ma);
|
164
|
+
#endif
|
165
|
+
for (int i = 0; i < 10; i++) {
|
166
|
+
map.insert(std::make_pair(i, (i % 2) == 0));
|
167
|
+
}
|
168
|
+
EXPECT_TRUE(map.size() == 10);
|
169
|
+
for (int i = 0; i < 10; i++) {
|
170
|
+
typename Map::iterator it = map.find(i);
|
171
|
+
EXPECT_TRUE(it != map.end());
|
172
|
+
EXPECT_TRUE(it->second == ((i % 2) == 0));
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
50
176
|
TEST(Allocator, CrtAllocator) {
|
51
177
|
CrtAllocator a;
|
178
|
+
|
52
179
|
TestAllocator(a);
|
180
|
+
TestStdAllocator(a);
|
181
|
+
|
182
|
+
CrtAllocator a2;
|
183
|
+
EXPECT_TRUE(a == a2);
|
184
|
+
EXPECT_FALSE(a != a2);
|
185
|
+
a2.Free(a2.Malloc(1));
|
186
|
+
EXPECT_TRUE(a == a2);
|
187
|
+
EXPECT_FALSE(a != a2);
|
53
188
|
}
|
54
189
|
|
55
190
|
TEST(Allocator, MemoryPoolAllocator) {
|
56
|
-
|
191
|
+
const size_t capacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY;
|
192
|
+
MemoryPoolAllocator<> a(capacity);
|
193
|
+
|
194
|
+
a.Clear(); // noop
|
195
|
+
EXPECT_EQ(a.Size(), 0u);
|
196
|
+
EXPECT_EQ(a.Capacity(), 0u);
|
197
|
+
EXPECT_EQ(a.Shared(), false);
|
198
|
+
{
|
199
|
+
MemoryPoolAllocator<> a2(a);
|
200
|
+
EXPECT_EQ(a2.Shared(), true);
|
201
|
+
EXPECT_EQ(a.Shared(), true);
|
202
|
+
EXPECT_TRUE(a == a2);
|
203
|
+
EXPECT_FALSE(a != a2);
|
204
|
+
a2.Free(a2.Malloc(1));
|
205
|
+
EXPECT_TRUE(a == a2);
|
206
|
+
EXPECT_FALSE(a != a2);
|
207
|
+
}
|
208
|
+
EXPECT_EQ(a.Shared(), false);
|
209
|
+
EXPECT_EQ(a.Capacity(), capacity);
|
210
|
+
EXPECT_EQ(a.Size(), 8u); // aligned
|
211
|
+
a.Clear();
|
212
|
+
EXPECT_EQ(a.Capacity(), 0u);
|
213
|
+
EXPECT_EQ(a.Size(), 0u);
|
214
|
+
|
57
215
|
TestAllocator(a);
|
216
|
+
TestStdAllocator(a);
|
58
217
|
|
59
218
|
for (size_t i = 1; i < 1000; i++) {
|
60
219
|
EXPECT_TRUE(a.Malloc(i) != 0);
|
61
220
|
EXPECT_LE(a.Size(), a.Capacity());
|
62
221
|
}
|
222
|
+
|
223
|
+
CrtAllocator baseAllocator;
|
224
|
+
a = MemoryPoolAllocator<>(capacity, &baseAllocator);
|
225
|
+
EXPECT_EQ(a.Capacity(), 0u);
|
226
|
+
EXPECT_EQ(a.Size(), 0u);
|
227
|
+
a.Free(a.Malloc(1));
|
228
|
+
EXPECT_EQ(a.Capacity(), capacity);
|
229
|
+
EXPECT_EQ(a.Size(), 8u); // aligned
|
230
|
+
|
231
|
+
{
|
232
|
+
a.Clear();
|
233
|
+
const size_t bufSize = 1024;
|
234
|
+
char *buffer = (char *)a.Malloc(bufSize);
|
235
|
+
MemoryPoolAllocator<> aligned_a(buffer, bufSize);
|
236
|
+
EXPECT_TRUE(aligned_a.Capacity() > 0 && aligned_a.Capacity() <= bufSize);
|
237
|
+
EXPECT_EQ(aligned_a.Size(), 0u);
|
238
|
+
aligned_a.Free(aligned_a.Malloc(1));
|
239
|
+
EXPECT_TRUE(aligned_a.Capacity() > 0 && aligned_a.Capacity() <= bufSize);
|
240
|
+
EXPECT_EQ(aligned_a.Size(), 8u); // aligned
|
241
|
+
}
|
242
|
+
|
243
|
+
{
|
244
|
+
a.Clear();
|
245
|
+
const size_t bufSize = 1024;
|
246
|
+
char *buffer = (char *)a.Malloc(bufSize);
|
247
|
+
RAPIDJSON_ASSERT(bufSize % sizeof(void*) == 0);
|
248
|
+
MemoryPoolAllocator<> unaligned_a(buffer + 1, bufSize - 1);
|
249
|
+
EXPECT_TRUE(unaligned_a.Capacity() > 0 && unaligned_a.Capacity() <= bufSize - sizeof(void*));
|
250
|
+
EXPECT_EQ(unaligned_a.Size(), 0u);
|
251
|
+
unaligned_a.Free(unaligned_a.Malloc(1));
|
252
|
+
EXPECT_TRUE(unaligned_a.Capacity() > 0 && unaligned_a.Capacity() <= bufSize - sizeof(void*));
|
253
|
+
EXPECT_EQ(unaligned_a.Size(), 8u); // aligned
|
254
|
+
}
|
63
255
|
}
|
64
256
|
|
65
257
|
TEST(Allocator, Alignment) {
|
@@ -325,6 +325,8 @@ TEST(Document, Swap) {
|
|
325
325
|
EXPECT_TRUE(d1.IsNull());
|
326
326
|
|
327
327
|
// reset document, including allocator
|
328
|
+
// so clear o before so that it doesnt contain dangling elements
|
329
|
+
o.Clear();
|
328
330
|
Document().Swap(d2);
|
329
331
|
EXPECT_TRUE(d2.IsNull());
|
330
332
|
EXPECT_NE(&d2.GetAllocator(), &a);
|
@@ -0,0 +1,40 @@
|
|
1
|
+
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
|
+
//
|
3
|
+
// Copyright (C) 2021 THL A29 Limited, a Tencent company, and Milo Yip.
|
4
|
+
//
|
5
|
+
// Licensed under the MIT License (the "License"); you may not use this file except
|
6
|
+
// in compliance with the License. You may obtain a copy of the License at
|
7
|
+
//
|
8
|
+
// http://opensource.org/licenses/MIT
|
9
|
+
//
|
10
|
+
// Unless required by applicable law or agreed to in writing, software distributed
|
11
|
+
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
12
|
+
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
13
|
+
// specific language governing permissions and limitations under the License.
|
14
|
+
|
15
|
+
#include "unittest.h"
|
16
|
+
|
17
|
+
// see https://github.com/Tencent/rapidjson/issues/1448
|
18
|
+
// including windows.h on purpose to provoke a compile time problem as GetObject is a
|
19
|
+
// macro that gets defined when windows.h is included
|
20
|
+
#ifdef _WIN32
|
21
|
+
#include <windows.h>
|
22
|
+
#endif
|
23
|
+
|
24
|
+
#include "rapidjson/document.h"
|
25
|
+
#undef GetObject
|
26
|
+
|
27
|
+
using namespace rapidjson;
|
28
|
+
|
29
|
+
TEST(Platform, GetObject) {
|
30
|
+
Document doc;
|
31
|
+
doc.Parse(" { \"object\" : { \"pi\": 3.1416} } ");
|
32
|
+
EXPECT_TRUE(doc.IsObject());
|
33
|
+
EXPECT_TRUE(doc.HasMember("object"));
|
34
|
+
const Document::ValueType& o = doc["object"];
|
35
|
+
EXPECT_TRUE(o.IsObject());
|
36
|
+
Value::ConstObject sub = o.GetObject();
|
37
|
+
EXPECT_TRUE(sub.HasMember("pi"));
|
38
|
+
Value::ConstObject sub2 = o.GetObj();
|
39
|
+
EXPECT_TRUE(sub2.HasMember("pi"));
|
40
|
+
}
|
@@ -475,7 +475,9 @@ TEST(Pointer, CopyConstructor) {
|
|
475
475
|
EXPECT_EQ(1u, q.GetTokens()[1].length);
|
476
476
|
EXPECT_STREQ("0", q.GetTokens()[1].name);
|
477
477
|
EXPECT_EQ(0u, q.GetTokens()[1].index);
|
478
|
-
|
478
|
+
|
479
|
+
// Copied pointer needs to have its own allocator
|
480
|
+
EXPECT_NE(&p.GetAllocator(), &q.GetAllocator());
|
479
481
|
}
|
480
482
|
|
481
483
|
// Static tokens
|
@@ -648,6 +650,52 @@ TEST(Pointer, Create) {
|
|
648
650
|
}
|
649
651
|
}
|
650
652
|
|
653
|
+
static const char kJsonIds[] = "{\n"
|
654
|
+
" \"id\": \"/root/\","
|
655
|
+
" \"foo\":[\"bar\", \"baz\", {\"id\": \"inarray\", \"child\": 1}],\n"
|
656
|
+
" \"int\" : 2,\n"
|
657
|
+
" \"str\" : \"val\",\n"
|
658
|
+
" \"obj\": {\"id\": \"inobj\", \"child\": 3},\n"
|
659
|
+
" \"jbo\": {\"id\": true, \"child\": 4}\n"
|
660
|
+
"}";
|
661
|
+
|
662
|
+
|
663
|
+
TEST(Pointer, GetUri) {
|
664
|
+
CrtAllocator allocator;
|
665
|
+
Document d;
|
666
|
+
d.Parse(kJsonIds);
|
667
|
+
Pointer::UriType doc("http://doc");
|
668
|
+
Pointer::UriType root("http://doc/root/");
|
669
|
+
Pointer::UriType empty = Pointer::UriType();
|
670
|
+
|
671
|
+
EXPECT_TRUE(Pointer("").GetUri(d, doc) == doc);
|
672
|
+
EXPECT_TRUE(Pointer("/foo").GetUri(d, doc) == root);
|
673
|
+
EXPECT_TRUE(Pointer("/foo/0").GetUri(d, doc) == root);
|
674
|
+
EXPECT_TRUE(Pointer("/foo/2").GetUri(d, doc) == root);
|
675
|
+
EXPECT_TRUE(Pointer("/foo/2/child").GetUri(d, doc) == Pointer::UriType("http://doc/root/inarray"));
|
676
|
+
EXPECT_TRUE(Pointer("/int").GetUri(d, doc) == root);
|
677
|
+
EXPECT_TRUE(Pointer("/str").GetUri(d, doc) == root);
|
678
|
+
EXPECT_TRUE(Pointer("/obj").GetUri(d, doc) == root);
|
679
|
+
EXPECT_TRUE(Pointer("/obj/child").GetUri(d, doc) == Pointer::UriType("http://doc/root/inobj"));
|
680
|
+
EXPECT_TRUE(Pointer("/jbo").GetUri(d, doc) == root);
|
681
|
+
EXPECT_TRUE(Pointer("/jbo/child").GetUri(d, doc) == root); // id not string
|
682
|
+
|
683
|
+
size_t unresolvedTokenIndex;
|
684
|
+
EXPECT_TRUE(Pointer("/abc").GetUri(d, doc, &unresolvedTokenIndex, &allocator) == empty); // Out of boundary
|
685
|
+
EXPECT_EQ(0u, unresolvedTokenIndex);
|
686
|
+
EXPECT_TRUE(Pointer("/foo/3").GetUri(d, doc, &unresolvedTokenIndex, &allocator) == empty); // Out of boundary
|
687
|
+
EXPECT_EQ(1u, unresolvedTokenIndex);
|
688
|
+
EXPECT_TRUE(Pointer("/foo/a").GetUri(d, doc, &unresolvedTokenIndex, &allocator) == empty); // "/foo" is an array, cannot query by "a"
|
689
|
+
EXPECT_EQ(1u, unresolvedTokenIndex);
|
690
|
+
EXPECT_TRUE(Pointer("/foo/0/0").GetUri(d, doc, &unresolvedTokenIndex, &allocator) == empty); // "/foo/0" is an string, cannot further query
|
691
|
+
EXPECT_EQ(2u, unresolvedTokenIndex);
|
692
|
+
EXPECT_TRUE(Pointer("/foo/0/a").GetUri(d, doc, &unresolvedTokenIndex, &allocator) == empty); // "/foo/0" is an string, cannot further query
|
693
|
+
EXPECT_EQ(2u, unresolvedTokenIndex);
|
694
|
+
|
695
|
+
Pointer::Token tokens[] = { { "foo ...", 3, kPointerInvalidIndex } };
|
696
|
+
EXPECT_TRUE(Pointer(tokens, 1).GetUri(d, doc) == root);
|
697
|
+
}
|
698
|
+
|
651
699
|
TEST(Pointer, Get) {
|
652
700
|
Document d;
|
653
701
|
d.Parse(kJson);
|
@@ -664,7 +712,8 @@ TEST(Pointer, Get) {
|
|
664
712
|
EXPECT_EQ(&d["k\"l"], Pointer("/k\"l").Get(d));
|
665
713
|
EXPECT_EQ(&d[" "], Pointer("/ ").Get(d));
|
666
714
|
EXPECT_EQ(&d["m~n"], Pointer("/m~0n").Get(d));
|
667
|
-
|
715
|
+
|
716
|
+
EXPECT_TRUE(Pointer("/abc").Get(d) == 0); // Out of boundary
|
668
717
|
size_t unresolvedTokenIndex;
|
669
718
|
EXPECT_TRUE(Pointer("/foo/2").Get(d, &unresolvedTokenIndex) == 0); // Out of boundary
|
670
719
|
EXPECT_EQ(1u, unresolvedTokenIndex);
|
@@ -1668,3 +1717,14 @@ TEST(Pointer, Issue483) {
|
|
1668
1717
|
value.SetString(mystr.c_str(), static_cast<SizeType>(mystr.length()), document.GetAllocator());
|
1669
1718
|
myjson::Pointer(path.c_str()).Set(document, value, document.GetAllocator());
|
1670
1719
|
}
|
1720
|
+
|
1721
|
+
TEST(Pointer, Issue1899) {
|
1722
|
+
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
|
1723
|
+
PointerType p;
|
1724
|
+
PointerType q = p.Append("foo");
|
1725
|
+
EXPECT_TRUE(PointerType("/foo") == q);
|
1726
|
+
q = q.Append(1234);
|
1727
|
+
EXPECT_TRUE(PointerType("/foo/1234") == q);
|
1728
|
+
q = q.Append("");
|
1729
|
+
EXPECT_TRUE(PointerType("/foo/1234/") == q);
|
1730
|
+
}
|