rj_schema 1.0.0 → 1.0.1
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 +1 -1
- data/lib/rj_schema.rb +1 -1
- metadata +9 -3
@@ -13,6 +13,7 @@
|
|
13
13
|
// specific language governing permissions and limitations under the License.
|
14
14
|
|
15
15
|
#define RAPIDJSON_SCHEMA_VERBOSE 0
|
16
|
+
#define RAPIDJSON_HAS_STDSTRING 1
|
16
17
|
|
17
18
|
#include "unittest.h"
|
18
19
|
#include "rapidjson/schema.h"
|
@@ -1811,6 +1812,189 @@ TEST(SchemaValidator, EscapedPointer) {
|
|
1811
1812
|
"}}");
|
1812
1813
|
}
|
1813
1814
|
|
1815
|
+
TEST(SchemaValidator, SchemaPointer) {
|
1816
|
+
Document sd;
|
1817
|
+
sd.Parse(
|
1818
|
+
"{"
|
1819
|
+
" \"swagger\": \"2.0\","
|
1820
|
+
" \"paths\": {"
|
1821
|
+
" \"/some/path\": {"
|
1822
|
+
" \"post\": {"
|
1823
|
+
" \"parameters\": ["
|
1824
|
+
" {"
|
1825
|
+
" \"in\": \"body\","
|
1826
|
+
" \"name\": \"body\","
|
1827
|
+
" \"schema\": {"
|
1828
|
+
" \"properties\": {"
|
1829
|
+
" \"a\": {"
|
1830
|
+
" \"$ref\": \"#/definitions/Prop_a\""
|
1831
|
+
" },"
|
1832
|
+
" \"b\": {"
|
1833
|
+
" \"type\": \"integer\""
|
1834
|
+
" }"
|
1835
|
+
" },"
|
1836
|
+
" \"type\": \"object\""
|
1837
|
+
" }"
|
1838
|
+
" }"
|
1839
|
+
" ],"
|
1840
|
+
" \"responses\": {"
|
1841
|
+
" \"200\": {"
|
1842
|
+
" \"schema\": {"
|
1843
|
+
" \"$ref\": \"#/definitions/Resp_200\""
|
1844
|
+
" }"
|
1845
|
+
" }"
|
1846
|
+
" }"
|
1847
|
+
" }"
|
1848
|
+
" }"
|
1849
|
+
" },"
|
1850
|
+
" \"definitions\": {"
|
1851
|
+
" \"Prop_a\": {"
|
1852
|
+
" \"properties\": {"
|
1853
|
+
" \"c\": {"
|
1854
|
+
" \"enum\": ["
|
1855
|
+
" \"C1\","
|
1856
|
+
" \"C2\","
|
1857
|
+
" \"C3\""
|
1858
|
+
" ],"
|
1859
|
+
" \"type\": \"string\""
|
1860
|
+
" },"
|
1861
|
+
" \"d\": {"
|
1862
|
+
" \"$ref\": \"#/definitions/Prop_d\""
|
1863
|
+
" },"
|
1864
|
+
" \"s\": {"
|
1865
|
+
" \"type\": \"string\""
|
1866
|
+
" }"
|
1867
|
+
" },"
|
1868
|
+
" \"required\": [\"c\"],"
|
1869
|
+
" \"type\": \"object\""
|
1870
|
+
" },"
|
1871
|
+
" \"Prop_d\": {"
|
1872
|
+
" \"properties\": {"
|
1873
|
+
" \"a\": {"
|
1874
|
+
" \"$ref\": \"#/definitions/Prop_a\""
|
1875
|
+
" },"
|
1876
|
+
" \"c\": {"
|
1877
|
+
" \"$ref\": \"#/definitions/Prop_a/properties/c\""
|
1878
|
+
" }"
|
1879
|
+
" },"
|
1880
|
+
" \"type\": \"object\""
|
1881
|
+
" },"
|
1882
|
+
" \"Resp_200\": {"
|
1883
|
+
" \"properties\": {"
|
1884
|
+
" \"e\": {"
|
1885
|
+
" \"type\": \"string\""
|
1886
|
+
" },"
|
1887
|
+
" \"f\": {"
|
1888
|
+
" \"type\": \"boolean\""
|
1889
|
+
" },"
|
1890
|
+
" \"cyclic_source\": {"
|
1891
|
+
" \"$ref\": \"#/definitions/Resp_200/properties/cyclic_target\""
|
1892
|
+
" },"
|
1893
|
+
" \"cyclic_target\": {"
|
1894
|
+
" \"$ref\": \"#/definitions/Resp_200/properties/cyclic_source\""
|
1895
|
+
" }"
|
1896
|
+
" },"
|
1897
|
+
" \"type\": \"object\""
|
1898
|
+
" }"
|
1899
|
+
" }"
|
1900
|
+
"}");
|
1901
|
+
SchemaDocument s1(sd, NULL, 0, NULL, NULL, Pointer("#/paths/~1some~1path/post/parameters/0/schema"));
|
1902
|
+
VALIDATE(s1,
|
1903
|
+
"{"
|
1904
|
+
" \"a\": {"
|
1905
|
+
" \"c\": \"C1\","
|
1906
|
+
" \"d\": {"
|
1907
|
+
" \"a\": {"
|
1908
|
+
" \"c\": \"C2\""
|
1909
|
+
" },"
|
1910
|
+
" \"c\": \"C3\""
|
1911
|
+
" }"
|
1912
|
+
" },"
|
1913
|
+
" \"b\": 123"
|
1914
|
+
"}",
|
1915
|
+
true);
|
1916
|
+
INVALIDATE(s1,
|
1917
|
+
"{"
|
1918
|
+
" \"a\": {"
|
1919
|
+
" \"c\": \"C1\","
|
1920
|
+
" \"d\": {"
|
1921
|
+
" \"a\": {"
|
1922
|
+
" \"c\": \"C2\""
|
1923
|
+
" },"
|
1924
|
+
" \"c\": \"C3\""
|
1925
|
+
" }"
|
1926
|
+
" },"
|
1927
|
+
" \"b\": \"should be an int\""
|
1928
|
+
"}",
|
1929
|
+
"#/paths/~1some~1path/post/parameters/0/schema/properties/b", "type", "#/b",
|
1930
|
+
"{ \"type\": {"
|
1931
|
+
" \"errorCode\": 20,"
|
1932
|
+
" \"instanceRef\":\"#/b\","
|
1933
|
+
" \"schemaRef\":\"#/paths/~1some~1path/post/parameters/0/schema/properties/b\","
|
1934
|
+
" \"expected\": [\"integer\"], \"actual\":\"string\""
|
1935
|
+
"}}");
|
1936
|
+
INVALIDATE(s1,
|
1937
|
+
"{"
|
1938
|
+
" \"a\": {"
|
1939
|
+
" \"c\": \"C1\","
|
1940
|
+
" \"d\": {"
|
1941
|
+
" \"a\": {"
|
1942
|
+
" \"c\": \"should be within enum\""
|
1943
|
+
" },"
|
1944
|
+
" \"c\": \"C3\""
|
1945
|
+
" }"
|
1946
|
+
" },"
|
1947
|
+
" \"b\": 123"
|
1948
|
+
"}",
|
1949
|
+
"#/definitions/Prop_a/properties/c", "enum", "#/a/d/a/c",
|
1950
|
+
"{ \"enum\": {"
|
1951
|
+
" \"errorCode\": 19,"
|
1952
|
+
" \"instanceRef\":\"#/a/d/a/c\","
|
1953
|
+
" \"schemaRef\":\"#/definitions/Prop_a/properties/c\""
|
1954
|
+
"}}");
|
1955
|
+
INVALIDATE(s1,
|
1956
|
+
"{"
|
1957
|
+
" \"a\": {"
|
1958
|
+
" \"c\": \"C1\","
|
1959
|
+
" \"d\": {"
|
1960
|
+
" \"a\": {"
|
1961
|
+
" \"s\": \"required 'c' is missing\""
|
1962
|
+
" }"
|
1963
|
+
" }"
|
1964
|
+
" },"
|
1965
|
+
" \"b\": 123"
|
1966
|
+
"}",
|
1967
|
+
"#/definitions/Prop_a", "required", "#/a/d/a",
|
1968
|
+
"{ \"required\": {"
|
1969
|
+
" \"errorCode\": 15,"
|
1970
|
+
" \"missing\":[\"c\"],"
|
1971
|
+
" \"instanceRef\":\"#/a/d/a\","
|
1972
|
+
" \"schemaRef\":\"#/definitions/Prop_a\""
|
1973
|
+
"}}");
|
1974
|
+
SchemaDocument s2(sd, NULL, 0, NULL, NULL, Pointer("#/paths/~1some~1path/post/responses/200/schema"));
|
1975
|
+
VALIDATE(s2,
|
1976
|
+
"{ \"e\": \"some string\", \"f\": false }",
|
1977
|
+
true);
|
1978
|
+
INVALIDATE(s2,
|
1979
|
+
"{ \"e\": true, \"f\": false }",
|
1980
|
+
"#/definitions/Resp_200/properties/e", "type", "#/e",
|
1981
|
+
"{ \"type\": {"
|
1982
|
+
" \"errorCode\": 20,"
|
1983
|
+
" \"instanceRef\":\"#/e\","
|
1984
|
+
" \"schemaRef\":\"#/definitions/Resp_200/properties/e\","
|
1985
|
+
" \"expected\": [\"string\"], \"actual\":\"boolean\""
|
1986
|
+
"}}");
|
1987
|
+
INVALIDATE(s2,
|
1988
|
+
"{ \"e\": \"some string\", \"f\": 123 }",
|
1989
|
+
"#/definitions/Resp_200/properties/f", "type", "#/f",
|
1990
|
+
"{ \"type\": {"
|
1991
|
+
" \"errorCode\": 20,"
|
1992
|
+
" \"instanceRef\":\"#/f\","
|
1993
|
+
" \"schemaRef\":\"#/definitions/Resp_200/properties/f\","
|
1994
|
+
" \"expected\": [\"boolean\"], \"actual\":\"integer\""
|
1995
|
+
"}}");
|
1996
|
+
}
|
1997
|
+
|
1814
1998
|
template <typename Allocator>
|
1815
1999
|
static char* ReadFile(const char* filename, Allocator& allocator) {
|
1816
2000
|
const char *paths[] = {
|
@@ -1952,7 +2136,7 @@ public:
|
|
1952
2136
|
|
1953
2137
|
virtual const SchemaDocumentType* GetRemoteDocument(const char* uri, SizeType length) {
|
1954
2138
|
for (size_t i = 0; i < kCount; i++)
|
1955
|
-
if (typename SchemaDocumentType::
|
2139
|
+
if (typename SchemaDocumentType::SValue(uri, length) == sd_[i]->GetURI())
|
1956
2140
|
return sd_[i];
|
1957
2141
|
return 0;
|
1958
2142
|
}
|
@@ -2032,7 +2216,7 @@ TEST(SchemaValidator, TestSuite) {
|
|
2032
2216
|
ADD_FAILURE();
|
2033
2217
|
}
|
2034
2218
|
else {
|
2035
|
-
//printf("
|
2219
|
+
//printf("\njson test suite file %s parsed ok\n", filename);
|
2036
2220
|
GenericDocument<UTF8<>, MemoryPoolAllocator<>, MemoryPoolAllocator<> > d(&documentAllocator, 1024, &documentStackAllocator);
|
2037
2221
|
d.Parse(json);
|
2038
2222
|
if (d.HasParseError()) {
|
@@ -2042,12 +2226,14 @@ TEST(SchemaValidator, TestSuite) {
|
|
2042
2226
|
else {
|
2043
2227
|
for (Value::ConstValueIterator schemaItr = d.Begin(); schemaItr != d.End(); ++schemaItr) {
|
2044
2228
|
{
|
2229
|
+
const char* description1 = (*schemaItr)["description"].GetString();
|
2230
|
+
//printf("\ncompiling schema for json test %s \n", description1);
|
2045
2231
|
SchemaDocumentType schema((*schemaItr)["schema"], filenames[i], static_cast<SizeType>(strlen(filenames[i])), &provider, &schemaAllocator);
|
2046
2232
|
GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > validator(schema, &validatorAllocator);
|
2047
|
-
const char* description1 = (*schemaItr)["description"].GetString();
|
2048
2233
|
const Value& tests = (*schemaItr)["tests"];
|
2049
2234
|
for (Value::ConstValueIterator testItr = tests.Begin(); testItr != tests.End(); ++testItr) {
|
2050
2235
|
const char* description2 = (*testItr)["description"].GetString();
|
2236
|
+
//printf("running json test %s \n", description2);
|
2051
2237
|
if (!onlyRunDescription || strcmp(description2, onlyRunDescription) == 0) {
|
2052
2238
|
const Value& data = (*testItr)["data"];
|
2053
2239
|
bool expected = (*testItr)["valid"].GetBool();
|
@@ -2075,8 +2261,8 @@ TEST(SchemaValidator, TestSuite) {
|
|
2075
2261
|
jsonAllocator.Clear();
|
2076
2262
|
}
|
2077
2263
|
printf("%d / %d passed (%2d%%)\n", passCount, testCount, passCount * 100 / testCount);
|
2078
|
-
|
2079
|
-
|
2264
|
+
if (passCount != testCount)
|
2265
|
+
ADD_FAILURE();
|
2080
2266
|
}
|
2081
2267
|
|
2082
2268
|
TEST(SchemaValidatingReader, Simple) {
|
@@ -2114,7 +2300,7 @@ TEST(SchemaValidatingReader, Invalid) {
|
|
2114
2300
|
Document e;
|
2115
2301
|
e.Parse(
|
2116
2302
|
"{ \"maxLength\": {"
|
2117
|
-
"
|
2303
|
+
" \"errorCode\": 6,"
|
2118
2304
|
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
|
2119
2305
|
" \"expected\": 3, \"actual\": \"ABCD\""
|
2120
2306
|
"}}");
|
@@ -2244,6 +2430,185 @@ TEST(SchemaValidator, Ref_remote) {
|
|
2244
2430
|
kValidateDefaultFlags, SchemaValidatorType, PointerType);
|
2245
2431
|
}
|
2246
2432
|
|
2433
|
+
// Merge with id where $ref is full URI
|
2434
|
+
TEST(SchemaValidator, Ref_remote_change_resolution_scope_uri) {
|
2435
|
+
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
2436
|
+
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
|
2437
|
+
Document sd;
|
2438
|
+
sd.Parse("{\"id\": \"http://ignore/blah#/ref\", \"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"http://localhost:1234/subSchemas.json#/integer\"}}}");
|
2439
|
+
SchemaDocumentType s(sd, 0, 0, &provider);
|
2440
|
+
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
|
2441
|
+
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
|
2442
|
+
INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt",
|
2443
|
+
"{ \"type\": {"
|
2444
|
+
" \"errorCode\": 20,"
|
2445
|
+
" \"instanceRef\": \"#/myInt\","
|
2446
|
+
" \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\","
|
2447
|
+
" \"expected\": [\"integer\"], \"actual\": \"null\""
|
2448
|
+
"}}",
|
2449
|
+
kValidateDefaultFlags, SchemaValidatorType, PointerType);
|
2450
|
+
}
|
2451
|
+
|
2452
|
+
// Merge with id where $ref is a relative path
|
2453
|
+
TEST(SchemaValidator, Ref_remote_change_resolution_scope_relative_path) {
|
2454
|
+
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
2455
|
+
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
|
2456
|
+
Document sd;
|
2457
|
+
sd.Parse("{\"id\": \"http://localhost:1234/\", \"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"subSchemas.json#/integer\"}}}");
|
2458
|
+
SchemaDocumentType s(sd, 0, 0, &provider);
|
2459
|
+
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
|
2460
|
+
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
|
2461
|
+
INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt",
|
2462
|
+
"{ \"type\": {"
|
2463
|
+
" \"errorCode\": 20,"
|
2464
|
+
" \"instanceRef\": \"#/myInt\","
|
2465
|
+
" \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\","
|
2466
|
+
" \"expected\": [\"integer\"], \"actual\": \"null\""
|
2467
|
+
"}}",
|
2468
|
+
kValidateDefaultFlags, SchemaValidatorType, PointerType);
|
2469
|
+
}
|
2470
|
+
|
2471
|
+
// Merge with id where $ref is an absolute path
|
2472
|
+
TEST(SchemaValidator, Ref_remote_change_resolution_scope_absolute_path) {
|
2473
|
+
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
2474
|
+
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
|
2475
|
+
Document sd;
|
2476
|
+
sd.Parse("{\"id\": \"http://localhost:1234/xxxx\", \"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/integer\"}}}");
|
2477
|
+
SchemaDocumentType s(sd, 0, 0, &provider);
|
2478
|
+
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
|
2479
|
+
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
|
2480
|
+
INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt",
|
2481
|
+
"{ \"type\": {"
|
2482
|
+
" \"errorCode\": 20,"
|
2483
|
+
" \"instanceRef\": \"#/myInt\","
|
2484
|
+
" \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\","
|
2485
|
+
" \"expected\": [\"integer\"], \"actual\": \"null\""
|
2486
|
+
"}}",
|
2487
|
+
kValidateDefaultFlags, SchemaValidatorType, PointerType);
|
2488
|
+
}
|
2489
|
+
|
2490
|
+
// Merge with id where $ref is an absolute path, and the document has a base URI
|
2491
|
+
TEST(SchemaValidator, Ref_remote_change_resolution_scope_absolute_path_document) {
|
2492
|
+
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
2493
|
+
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
|
2494
|
+
Document sd;
|
2495
|
+
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/integer\"}}}");
|
2496
|
+
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider);
|
2497
|
+
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
|
2498
|
+
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
|
2499
|
+
INVALIDATE_(s, "{\"myInt\": null}", "/integer", "type", "/myInt",
|
2500
|
+
"{ \"type\": {"
|
2501
|
+
" \"errorCode\": 20,"
|
2502
|
+
" \"instanceRef\": \"#/myInt\","
|
2503
|
+
" \"schemaRef\": \"http://localhost:1234/subSchemas.json#/integer\","
|
2504
|
+
" \"expected\": [\"integer\"], \"actual\": \"null\""
|
2505
|
+
"}}",
|
2506
|
+
kValidateDefaultFlags, SchemaValidatorType, PointerType);
|
2507
|
+
}
|
2508
|
+
|
2509
|
+
// $ref is a non-JSON pointer fragment and there a matching id
|
2510
|
+
TEST(SchemaValidator, Ref_internal_id_1) {
|
2511
|
+
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
2512
|
+
Document sd;
|
2513
|
+
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myStr\": {\"type\": \"string\", \"id\": \"#myStrId\"}, \"myInt2\": {\"type\": \"integer\", \"id\": \"#myId\"}}}");
|
2514
|
+
SchemaDocumentType s(sd);
|
2515
|
+
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
|
2516
|
+
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
|
2517
|
+
INVALIDATE_(s, "{\"myInt1\": null}", "/properties/myInt2", "type", "/myInt1",
|
2518
|
+
"{ \"type\": {"
|
2519
|
+
" \"errorCode\": 20,"
|
2520
|
+
" \"instanceRef\": \"#/myInt1\","
|
2521
|
+
" \"schemaRef\": \"#/properties/myInt2\","
|
2522
|
+
" \"expected\": [\"integer\"], \"actual\": \"null\""
|
2523
|
+
"}}",
|
2524
|
+
kValidateDefaultFlags, SchemaValidatorType, PointerType);
|
2525
|
+
}
|
2526
|
+
|
2527
|
+
// $ref is a non-JSON pointer fragment and there are two matching ids so we take the first
|
2528
|
+
TEST(SchemaValidator, Ref_internal_id_2) {
|
2529
|
+
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
2530
|
+
Document sd;
|
2531
|
+
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myInt2\": {\"type\": \"integer\", \"id\": \"#myId\"}, \"myStr\": {\"type\": \"string\", \"id\": \"#myId\"}}}");
|
2532
|
+
SchemaDocumentType s(sd);
|
2533
|
+
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
|
2534
|
+
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
|
2535
|
+
INVALIDATE_(s, "{\"myInt1\": null}", "/properties/myInt2", "type", "/myInt1",
|
2536
|
+
"{ \"type\": {"
|
2537
|
+
" \"errorCode\": 20,"
|
2538
|
+
" \"instanceRef\": \"#/myInt1\","
|
2539
|
+
" \"schemaRef\": \"#/properties/myInt2\","
|
2540
|
+
" \"expected\": [\"integer\"], \"actual\": \"null\""
|
2541
|
+
"}}",
|
2542
|
+
kValidateDefaultFlags, SchemaValidatorType, PointerType);
|
2543
|
+
}
|
2544
|
+
|
2545
|
+
// $ref is a non-JSON pointer fragment and there is a matching id within array
|
2546
|
+
TEST(SchemaValidator, Ref_internal_id_in_array) {
|
2547
|
+
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
2548
|
+
Document sd;
|
2549
|
+
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myInt2\": {\"anyOf\": [{\"type\": \"string\", \"id\": \"#myStrId\"}, {\"type\": \"integer\", \"id\": \"#myId\"}]}}}");
|
2550
|
+
SchemaDocumentType s(sd);
|
2551
|
+
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
|
2552
|
+
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
|
2553
|
+
INVALIDATE_(s, "{\"myInt1\": null}", "/properties/myInt2/anyOf/1", "type", "/myInt1",
|
2554
|
+
"{ \"type\": {"
|
2555
|
+
" \"errorCode\": 20,"
|
2556
|
+
" \"instanceRef\": \"#/myInt1\","
|
2557
|
+
" \"schemaRef\": \"#/properties/myInt2/anyOf/1\","
|
2558
|
+
" \"expected\": [\"integer\"], \"actual\": \"null\""
|
2559
|
+
"}}",
|
2560
|
+
kValidateDefaultFlags, SchemaValidatorType, PointerType);
|
2561
|
+
}
|
2562
|
+
|
2563
|
+
// $ref is a non-JSON pointer fragment and there is a matching id, and the schema is embedded in the document
|
2564
|
+
TEST(SchemaValidator, Ref_internal_id_and_schema_pointer) {
|
2565
|
+
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
2566
|
+
Document sd;
|
2567
|
+
sd.Parse("{ \"schema\": {\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myInt2\": {\"anyOf\": [{\"type\": \"integer\", \"id\": \"#myId\"}]}}}}");
|
2568
|
+
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
|
2569
|
+
SchemaDocumentType s(sd, 0, 0, 0, 0, PointerType("/schema"));
|
2570
|
+
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
|
2571
|
+
INVALIDATE_(s, "{\"myInt1\": null}", "/schema/properties/myInt2/anyOf/0", "type", "/myInt1",
|
2572
|
+
"{ \"type\": {"
|
2573
|
+
" \"errorCode\": 20,"
|
2574
|
+
" \"instanceRef\": \"#/myInt1\","
|
2575
|
+
" \"schemaRef\": \"#/schema/properties/myInt2/anyOf/0\","
|
2576
|
+
" \"expected\": [\"integer\"], \"actual\": \"null\""
|
2577
|
+
"}}",
|
2578
|
+
kValidateDefaultFlags, SchemaValidatorType, PointerType);
|
2579
|
+
}
|
2580
|
+
|
2581
|
+
// Test that $refs are correctly resolved when intermediate multiple ids are present
|
2582
|
+
// Includes $ref to a part of the document with a different in-scope id, which also contains $ref..
|
2583
|
+
TEST(SchemaValidator, Ref_internal_multiple_ids) {
|
2584
|
+
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
2585
|
+
//RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
|
2586
|
+
CrtAllocator allocator;
|
2587
|
+
char* schema = ReadFile("unittestschema/idandref.json", allocator);
|
2588
|
+
Document sd;
|
2589
|
+
sd.Parse(schema);
|
2590
|
+
ASSERT_FALSE(sd.HasParseError());
|
2591
|
+
SchemaDocumentType s(sd, "http://xyz", 10/*, &provider*/);
|
2592
|
+
typedef GenericSchemaValidator<SchemaDocumentType, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > SchemaValidatorType;
|
2593
|
+
typedef GenericPointer<Value, MemoryPoolAllocator<> > PointerType;
|
2594
|
+
INVALIDATE_(s, "{\"PA1\": \"s\", \"PA2\": \"t\", \"PA3\": \"r\", \"PX1\": 1, \"PX2Y\": 2, \"PX3Z\": 3, \"PX4\": 4, \"PX5\": 5, \"PX6\": 6, \"PX7W\": 7, \"PX8N\": { \"NX\": 8}}", "#", "errors", "#",
|
2595
|
+
"{ \"type\": ["
|
2596
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PA1\", \"schemaRef\": \"http://xyz#/definitions/A\", \"expected\": [\"integer\"], \"actual\": \"string\"},"
|
2597
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PA2\", \"schemaRef\": \"http://xyz#/definitions/A\", \"expected\": [\"integer\"], \"actual\": \"string\"},"
|
2598
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PA3\", \"schemaRef\": \"http://xyz#/definitions/A\", \"expected\": [\"integer\"], \"actual\": \"string\"},"
|
2599
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PX1\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
|
2600
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PX2Y\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
|
2601
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PX3Z\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
|
2602
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PX4\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
|
2603
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PX5\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
|
2604
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PX6\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
|
2605
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PX7W\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"},"
|
2606
|
+
" {\"errorCode\": 20, \"instanceRef\": \"#/PX8N/NX\", \"schemaRef\": \"http://xyz#/definitions/B/definitions/X\", \"expected\": [\"boolean\"], \"actual\": \"integer\"}"
|
2607
|
+
"]}",
|
2608
|
+
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidatorType, PointerType);
|
2609
|
+
CrtAllocator::Free(schema);
|
2610
|
+
}
|
2611
|
+
|
2247
2612
|
TEST(SchemaValidator, Ref_remote_issue1210) {
|
2248
2613
|
class SchemaDocumentProvider : public IRemoteSchemaDocumentProvider {
|
2249
2614
|
SchemaDocument** collection;
|
@@ -2260,7 +2625,7 @@ TEST(SchemaValidator, Ref_remote_issue1210) {
|
|
2260
2625
|
SchemaDocumentProvider(SchemaDocument** collection) : collection(collection) { }
|
2261
2626
|
virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) {
|
2262
2627
|
int i = 0;
|
2263
|
-
while (collection[i] && SchemaDocument::
|
2628
|
+
while (collection[i] && SchemaDocument::SValue(uri, length) != collection[i]->GetURI()) ++i;
|
2264
2629
|
return collection[i];
|
2265
2630
|
}
|
2266
2631
|
};
|
@@ -0,0 +1,718 @@
|
|
1
|
+
// Tencent is pleased to support the open source community by making RapidJSON available.
|
2
|
+
//
|
3
|
+
// (C) Copyright IBM Corporation 2021
|
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
|
+
#define RAPIDJSON_SCHEMA_VERBOSE 0
|
16
|
+
#define RAPIDJSON_HAS_STDSTRING 1
|
17
|
+
|
18
|
+
#include "unittest.h"
|
19
|
+
#include "rapidjson/document.h"
|
20
|
+
#include "rapidjson/uri.h"
|
21
|
+
|
22
|
+
#ifdef __clang__
|
23
|
+
RAPIDJSON_DIAG_PUSH
|
24
|
+
RAPIDJSON_DIAG_OFF(variadic-macros)
|
25
|
+
#elif defined(_MSC_VER)
|
26
|
+
RAPIDJSON_DIAG_PUSH
|
27
|
+
RAPIDJSON_DIAG_OFF(4822) // local class member function does not have a body
|
28
|
+
#endif
|
29
|
+
|
30
|
+
using namespace rapidjson;
|
31
|
+
|
32
|
+
TEST(Uri, DefaultConstructor) {
|
33
|
+
typedef GenericUri<Value> UriType;
|
34
|
+
UriType u;
|
35
|
+
EXPECT_TRUE(u.GetSchemeString() == 0);
|
36
|
+
EXPECT_TRUE(u.GetAuthString() == 0);
|
37
|
+
EXPECT_TRUE(u.GetPathString() == 0);
|
38
|
+
EXPECT_TRUE(u.GetBaseString() == 0);
|
39
|
+
EXPECT_TRUE(u.GetQueryString() == 0);
|
40
|
+
EXPECT_TRUE(u.GetFragString() == 0);
|
41
|
+
EXPECT_TRUE(u.GetString() == 0);
|
42
|
+
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
43
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
44
|
+
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
45
|
+
EXPECT_TRUE(u.GetBaseStringLength() == 0);
|
46
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
47
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
48
|
+
EXPECT_TRUE(u.GetStringLength() == 0);
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
TEST(Uri, Parse) {
|
53
|
+
typedef GenericUri<Value, MemoryPoolAllocator<> > UriType;
|
54
|
+
MemoryPoolAllocator<CrtAllocator> allocator;
|
55
|
+
Value v;
|
56
|
+
Value w;
|
57
|
+
|
58
|
+
v.SetString("http://auth/path/xxx?query#frag", allocator);
|
59
|
+
UriType u = UriType(v, &allocator);
|
60
|
+
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0);
|
61
|
+
EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0);
|
62
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), "/path/xxx") == 0);
|
63
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), "http://auth/path/xxx?query") == 0);
|
64
|
+
EXPECT_TRUE(StrCmp(u.GetQueryString(), "?query") == 0);
|
65
|
+
EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag") == 0);
|
66
|
+
u.Get(w, allocator);
|
67
|
+
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
68
|
+
|
69
|
+
#if RAPIDJSON_HAS_STDSTRING
|
70
|
+
typedef std::basic_string<Value::Ch> String;
|
71
|
+
String str = "http://auth/path/xxx?query#frag";
|
72
|
+
const UriType uri = UriType(str);
|
73
|
+
EXPECT_TRUE(UriType::GetScheme(uri) == "http:");
|
74
|
+
EXPECT_TRUE(UriType::GetAuth(uri) == "//auth");
|
75
|
+
EXPECT_TRUE(UriType::GetPath(uri) == "/path/xxx");
|
76
|
+
EXPECT_TRUE(UriType::GetBase(uri) == "http://auth/path/xxx?query");
|
77
|
+
EXPECT_TRUE(UriType::GetQuery(uri) == "?query");
|
78
|
+
EXPECT_TRUE(UriType::GetFrag(uri) == "#frag");
|
79
|
+
EXPECT_TRUE(UriType::Get(uri) == str);
|
80
|
+
#endif
|
81
|
+
|
82
|
+
v.SetString("urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator);
|
83
|
+
u = UriType(v);
|
84
|
+
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "urn:") == 0);
|
85
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
86
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), "uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
87
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
88
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
89
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
90
|
+
u.Get(w, allocator);
|
91
|
+
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
92
|
+
|
93
|
+
v.SetString("", allocator);
|
94
|
+
u = UriType(v);
|
95
|
+
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
96
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
97
|
+
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
98
|
+
EXPECT_TRUE(u.GetBaseStringLength() == 0);
|
99
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
100
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
101
|
+
|
102
|
+
v.SetString("http://auth/", allocator);
|
103
|
+
u = UriType(v);
|
104
|
+
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0);
|
105
|
+
EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0);
|
106
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), "/") == 0);
|
107
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), "http://auth/") == 0);
|
108
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
109
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
110
|
+
|
111
|
+
u = UriType("/path/sub");
|
112
|
+
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
113
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
114
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), "/path/sub") == 0);
|
115
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), "/path/sub") == 0);
|
116
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
117
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
118
|
+
|
119
|
+
// absolute path gets normalized
|
120
|
+
u = UriType("/path/../sub/");
|
121
|
+
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
122
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
123
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), "/sub/") == 0);
|
124
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), "/sub/") == 0);
|
125
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
126
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
127
|
+
|
128
|
+
// relative path does not
|
129
|
+
u = UriType("path/../sub");
|
130
|
+
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
131
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
132
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), "path/../sub") == 0);
|
133
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), "path/../sub") == 0);
|
134
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
135
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
136
|
+
|
137
|
+
u = UriType("http://auth#frag/stuff");
|
138
|
+
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0);
|
139
|
+
EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0);
|
140
|
+
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
141
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), "http://auth") == 0);
|
142
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
143
|
+
EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag/stuff") == 0);
|
144
|
+
EXPECT_TRUE(StrCmp(u.GetString(), "http://auth#frag/stuff") == 0);
|
145
|
+
|
146
|
+
const Value::Ch c[] = { '#', 'f', 'r', 'a', 'g', '/', 's', 't', 'u', 'f', 'f', '\0'};
|
147
|
+
SizeType len = internal::StrLen<Value::Ch>(c);
|
148
|
+
u = UriType(c, len);
|
149
|
+
EXPECT_TRUE(StrCmp(u.GetString(), "#frag/stuff") == 0);
|
150
|
+
EXPECT_TRUE(u.GetStringLength() == len);
|
151
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), "") == 0);
|
152
|
+
EXPECT_TRUE(u.GetBaseStringLength() == 0);
|
153
|
+
EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag/stuff") == 0);
|
154
|
+
EXPECT_TRUE(u.GetFragStringLength() == len);
|
155
|
+
|
156
|
+
u = UriType(c);
|
157
|
+
EXPECT_TRUE(StrCmp(u.GetString(), "#frag/stuff") == 0);
|
158
|
+
EXPECT_TRUE(u.GetStringLength() == len);
|
159
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), "") == 0);
|
160
|
+
EXPECT_TRUE(u.GetBaseStringLength() == 0);
|
161
|
+
EXPECT_TRUE(StrCmp(u.GetFragString(), "#frag/stuff") == 0);
|
162
|
+
EXPECT_TRUE(u.GetFragStringLength() == len);
|
163
|
+
|
164
|
+
// Incomplete auth treated as path
|
165
|
+
str = "http:/";
|
166
|
+
const UriType u2 = UriType(str);
|
167
|
+
EXPECT_TRUE(StrCmp(u2.GetSchemeString(), "http:") == 0);
|
168
|
+
EXPECT_TRUE(u2.GetAuthStringLength() == 0);
|
169
|
+
EXPECT_TRUE(StrCmp(u2.GetPathString(), "/") == 0);
|
170
|
+
EXPECT_TRUE(StrCmp(u2.GetBaseString(), "http:/") == 0);
|
171
|
+
}
|
172
|
+
|
173
|
+
TEST(Uri, Parse_UTF16) {
|
174
|
+
typedef GenericValue<UTF16<> > Value16;
|
175
|
+
typedef GenericUri<Value16, MemoryPoolAllocator<> > UriType;
|
176
|
+
MemoryPoolAllocator<CrtAllocator> allocator;
|
177
|
+
Value16 v;
|
178
|
+
Value16 w;
|
179
|
+
|
180
|
+
v.SetString(L"http://auth/path/xxx?query#frag", allocator);
|
181
|
+
UriType u = UriType(v, &allocator);
|
182
|
+
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0);
|
183
|
+
EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0);
|
184
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), L"/path/xxx") == 0);
|
185
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http://auth/path/xxx?query") == 0);
|
186
|
+
EXPECT_TRUE(StrCmp(u.GetQueryString(), L"?query") == 0);
|
187
|
+
EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag") == 0);
|
188
|
+
u.Get(w, allocator);
|
189
|
+
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
190
|
+
|
191
|
+
#if RAPIDJSON_HAS_STDSTRING
|
192
|
+
typedef std::basic_string<Value16::Ch> String;
|
193
|
+
String str = L"http://auth/path/xxx?query#frag";
|
194
|
+
const UriType uri = UriType(str);
|
195
|
+
EXPECT_TRUE(UriType::GetScheme(uri) == L"http:");
|
196
|
+
EXPECT_TRUE(UriType::GetAuth(uri) == L"//auth");
|
197
|
+
EXPECT_TRUE(UriType::GetPath(uri) == L"/path/xxx");
|
198
|
+
EXPECT_TRUE(UriType::GetBase(uri) == L"http://auth/path/xxx?query");
|
199
|
+
EXPECT_TRUE(UriType::GetQuery(uri) == L"?query");
|
200
|
+
EXPECT_TRUE(UriType::GetFrag(uri) == L"#frag");
|
201
|
+
EXPECT_TRUE(UriType::Get(uri) == str);
|
202
|
+
#endif
|
203
|
+
|
204
|
+
v.SetString(L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator);
|
205
|
+
u = UriType(v);
|
206
|
+
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"urn:") == 0);
|
207
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
208
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), L"uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
209
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
210
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
211
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
212
|
+
u.Get(w, allocator);
|
213
|
+
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
214
|
+
|
215
|
+
v.SetString(L"", allocator);
|
216
|
+
u = UriType(v);
|
217
|
+
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
218
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
219
|
+
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
220
|
+
EXPECT_TRUE(u.GetBaseStringLength() == 0);
|
221
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
222
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
223
|
+
|
224
|
+
v.SetString(L"http://auth/", allocator);
|
225
|
+
u = UriType(v);
|
226
|
+
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0);
|
227
|
+
EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0);
|
228
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), L"/") == 0);
|
229
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http://auth/") == 0);
|
230
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
231
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
232
|
+
|
233
|
+
u = UriType(L"/path/sub");
|
234
|
+
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
235
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
236
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), L"/path/sub") == 0);
|
237
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"/path/sub") == 0);
|
238
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
239
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
240
|
+
|
241
|
+
// absolute path gets normalized
|
242
|
+
u = UriType(L"/path/../sub/");
|
243
|
+
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
244
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
245
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), L"/sub/") == 0);
|
246
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"/sub/") == 0);
|
247
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
248
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
249
|
+
|
250
|
+
// relative path does not
|
251
|
+
u = UriType(L"path/../sub");
|
252
|
+
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
253
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
254
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), L"path/../sub") == 0);
|
255
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"path/../sub") == 0);
|
256
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
257
|
+
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
258
|
+
|
259
|
+
u = UriType(L"http://auth#frag/stuff");
|
260
|
+
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0);
|
261
|
+
EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0);
|
262
|
+
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
263
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http://auth") == 0);
|
264
|
+
EXPECT_TRUE(u.GetQueryStringLength() == 0);
|
265
|
+
EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag/stuff") == 0);
|
266
|
+
EXPECT_TRUE(StrCmp(u.GetString(), L"http://auth#frag/stuff") == 0);
|
267
|
+
|
268
|
+
const Value16::Ch c[] = { '#', 'f', 'r', 'a', 'g', '/', 's', 't', 'u', 'f', 'f', '\0'};
|
269
|
+
SizeType len = internal::StrLen<Value16::Ch>(c);
|
270
|
+
u = UriType(c, len);
|
271
|
+
EXPECT_TRUE(StrCmp(u.GetString(), L"#frag/stuff") == 0);
|
272
|
+
EXPECT_TRUE(u.GetStringLength() == len);
|
273
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"") == 0);
|
274
|
+
EXPECT_TRUE(u.GetBaseStringLength() == 0);
|
275
|
+
EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag/stuff") == 0);
|
276
|
+
EXPECT_TRUE(u.GetFragStringLength() == len);
|
277
|
+
|
278
|
+
u = UriType(c);
|
279
|
+
EXPECT_TRUE(StrCmp(u.GetString(), L"#frag/stuff") == 0);
|
280
|
+
EXPECT_TRUE(u.GetStringLength() == len);
|
281
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"") == 0);
|
282
|
+
EXPECT_TRUE(u.GetBaseStringLength() == 0);
|
283
|
+
EXPECT_TRUE(StrCmp(u.GetFragString(), L"#frag/stuff") == 0);
|
284
|
+
EXPECT_TRUE(u.GetFragStringLength() == len);
|
285
|
+
|
286
|
+
// Incomplete auth treated as path
|
287
|
+
u = UriType(L"http:/");
|
288
|
+
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0);
|
289
|
+
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
290
|
+
EXPECT_TRUE(StrCmp(u.GetPathString(), L"/") == 0);
|
291
|
+
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http:/") == 0);
|
292
|
+
}
|
293
|
+
|
294
|
+
TEST(Uri, CopyConstructor) {
|
295
|
+
typedef GenericUri<Value> UriType;
|
296
|
+
CrtAllocator allocator;
|
297
|
+
|
298
|
+
UriType u("http://auth/path/xxx?query#frag", &allocator);
|
299
|
+
UriType u2(u);
|
300
|
+
EXPECT_TRUE(u == u2);
|
301
|
+
EXPECT_NE(&u.GetAllocator(), &u2.GetAllocator());
|
302
|
+
}
|
303
|
+
|
304
|
+
TEST(Uri, Assignment) {
|
305
|
+
typedef GenericUri<Value> UriType;
|
306
|
+
CrtAllocator allocator;
|
307
|
+
|
308
|
+
UriType u("http://auth/path/xxx?query#frag", &allocator);
|
309
|
+
UriType u2;
|
310
|
+
u2 = u;
|
311
|
+
EXPECT_TRUE(u == u2);
|
312
|
+
EXPECT_NE(&u.GetAllocator(), &u2.GetAllocator());
|
313
|
+
}
|
314
|
+
|
315
|
+
TEST(Uri, Resolve) {
|
316
|
+
typedef GenericUri<Value> UriType;
|
317
|
+
CrtAllocator allocator;
|
318
|
+
|
319
|
+
// ref is full uri
|
320
|
+
UriType base = UriType("http://auth/path/#frag");
|
321
|
+
UriType ref = UriType("http://newauth/newpath#newfrag");
|
322
|
+
UriType res = ref.Resolve(base);
|
323
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://newauth/newpath#newfrag") == 0);
|
324
|
+
|
325
|
+
base = UriType("/path/#frag", &allocator);
|
326
|
+
ref = UriType("http://newauth/newpath#newfrag", &allocator);
|
327
|
+
res = ref.Resolve(base, &allocator);
|
328
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://newauth/newpath#newfrag") == 0);
|
329
|
+
|
330
|
+
// ref is alternate uri
|
331
|
+
base = UriType("http://auth/path/#frag");
|
332
|
+
ref = UriType("urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f");
|
333
|
+
res = ref.Resolve(base);
|
334
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
335
|
+
|
336
|
+
// ref is absolute path
|
337
|
+
base = UriType("http://auth/path/#");
|
338
|
+
ref = UriType("/newpath#newfrag");
|
339
|
+
res = ref.Resolve(base);
|
340
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/newpath#newfrag") == 0);
|
341
|
+
|
342
|
+
// ref is relative path
|
343
|
+
base = UriType("http://auth/path/file.json#frag");
|
344
|
+
ref = UriType("newfile.json#");
|
345
|
+
res = ref.Resolve(base);
|
346
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/path/newfile.json#") == 0);
|
347
|
+
|
348
|
+
base = UriType("http://auth/path/file.json#frag/stuff");
|
349
|
+
ref = UriType("newfile.json#newfrag/newstuff");
|
350
|
+
res = ref.Resolve(base);
|
351
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/path/newfile.json#newfrag/newstuff") == 0);
|
352
|
+
|
353
|
+
base = UriType("file.json", &allocator);
|
354
|
+
ref = UriType("newfile.json", &base.GetAllocator());
|
355
|
+
res = ref.Resolve(base, &ref.GetAllocator());
|
356
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0);
|
357
|
+
|
358
|
+
base = UriType("file.json", &allocator);
|
359
|
+
ref = UriType("./newfile.json", &allocator);
|
360
|
+
res = ref.Resolve(base, &allocator);
|
361
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0);
|
362
|
+
|
363
|
+
base = UriType("file.json");
|
364
|
+
ref = UriType("parent/../newfile.json");
|
365
|
+
res = ref.Resolve(base);
|
366
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0);
|
367
|
+
|
368
|
+
base = UriType("file.json");
|
369
|
+
ref = UriType("parent/./newfile.json");
|
370
|
+
res = ref.Resolve(base);
|
371
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "parent/newfile.json") == 0);
|
372
|
+
|
373
|
+
base = UriType("file.json");
|
374
|
+
ref = UriType("../../parent/.././newfile.json");
|
375
|
+
res = ref.Resolve(base);
|
376
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "newfile.json") == 0);
|
377
|
+
|
378
|
+
// This adds a joining slash so resolved length is base length + ref length + 1
|
379
|
+
base = UriType("http://auth");
|
380
|
+
ref = UriType("newfile.json");
|
381
|
+
res = ref.Resolve(base);
|
382
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://auth/newfile.json") == 0);
|
383
|
+
|
384
|
+
// ref is fragment
|
385
|
+
base = UriType("#frag/stuff");
|
386
|
+
ref = UriType("#newfrag/newstuff");
|
387
|
+
res = ref.Resolve(base);
|
388
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "#newfrag/newstuff") == 0);
|
389
|
+
|
390
|
+
// test ref fragment always wins
|
391
|
+
base = UriType("/path#frag");
|
392
|
+
ref = UriType("");
|
393
|
+
res = ref.Resolve(base);
|
394
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "/path") == 0);
|
395
|
+
|
396
|
+
// Examples from RFC3896
|
397
|
+
base = UriType("http://a/b/c/d;p?q");
|
398
|
+
ref = UriType("g:h");
|
399
|
+
res = ref.Resolve(base);
|
400
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "g:h") == 0);
|
401
|
+
ref = UriType("g");
|
402
|
+
res = ref.Resolve(base);
|
403
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g") == 0);
|
404
|
+
ref = UriType("./g");
|
405
|
+
res = ref.Resolve(base);
|
406
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g") == 0);
|
407
|
+
ref = UriType("g/");
|
408
|
+
res = ref.Resolve(base);
|
409
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g/") == 0);
|
410
|
+
ref = UriType("/g");
|
411
|
+
res = ref.Resolve(base);
|
412
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0);
|
413
|
+
ref = UriType("//g");
|
414
|
+
res = ref.Resolve(base);
|
415
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://g") == 0);
|
416
|
+
ref = UriType("?y");
|
417
|
+
res = ref.Resolve(base);
|
418
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/d;p?y") == 0);
|
419
|
+
ref = UriType("g?y");
|
420
|
+
res = ref.Resolve(base);
|
421
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g?y") == 0);
|
422
|
+
ref = UriType("#s");
|
423
|
+
res = ref.Resolve(base);
|
424
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/d;p?q#s") == 0);
|
425
|
+
ref = UriType("g#s");
|
426
|
+
res = ref.Resolve(base);
|
427
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g#s") == 0);
|
428
|
+
ref = UriType("g?y#s");
|
429
|
+
res = ref.Resolve(base);
|
430
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g?y#s") == 0);
|
431
|
+
ref = UriType(";x");
|
432
|
+
res = ref.Resolve(base);
|
433
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/;x") == 0);
|
434
|
+
ref = UriType("g;x");
|
435
|
+
res = ref.Resolve(base);
|
436
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g;x") == 0);
|
437
|
+
ref = UriType("g;x?y#s");
|
438
|
+
res = ref.Resolve(base);
|
439
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g;x?y#s") == 0);
|
440
|
+
ref = UriType("");
|
441
|
+
res = ref.Resolve(base);
|
442
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/d;p?q") == 0);
|
443
|
+
ref = UriType(".");
|
444
|
+
res = ref.Resolve(base);
|
445
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/") == 0);
|
446
|
+
ref = UriType("./");
|
447
|
+
res = ref.Resolve(base);
|
448
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/") == 0);
|
449
|
+
ref = UriType("..");
|
450
|
+
res = ref.Resolve(base);
|
451
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/") == 0);
|
452
|
+
ref = UriType("../");
|
453
|
+
res = ref.Resolve(base);
|
454
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/") == 0);
|
455
|
+
ref = UriType("../g");
|
456
|
+
res = ref.Resolve(base);
|
457
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/g") == 0);
|
458
|
+
ref = UriType("../..");
|
459
|
+
res = ref.Resolve(base);
|
460
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/") == 0);
|
461
|
+
ref = UriType("../../");
|
462
|
+
res = ref.Resolve(base);
|
463
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/") == 0);
|
464
|
+
ref = UriType("../../g");
|
465
|
+
res = ref.Resolve(base);
|
466
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0);
|
467
|
+
ref = UriType("../../../g");
|
468
|
+
res = ref.Resolve(base);
|
469
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0);
|
470
|
+
ref = UriType("../../../../g");
|
471
|
+
res = ref.Resolve(base);
|
472
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0);
|
473
|
+
ref = UriType("/./g");
|
474
|
+
res = ref.Resolve(base);
|
475
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0);
|
476
|
+
ref = UriType("/../g");
|
477
|
+
res = ref.Resolve(base);
|
478
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/g") == 0);
|
479
|
+
ref = UriType("g.");
|
480
|
+
res = ref.Resolve(base);
|
481
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g.") == 0);
|
482
|
+
ref = UriType(".g");
|
483
|
+
res = ref.Resolve(base);
|
484
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/.g") == 0);
|
485
|
+
ref = UriType("g..");
|
486
|
+
res = ref.Resolve(base);
|
487
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g..") == 0);
|
488
|
+
ref = UriType("..g");
|
489
|
+
res = ref.Resolve(base);
|
490
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/..g") == 0);
|
491
|
+
ref = UriType("g#s/../x");
|
492
|
+
res = ref.Resolve(base);
|
493
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://a/b/c/g#s/../x") == 0);
|
494
|
+
}
|
495
|
+
|
496
|
+
TEST(Uri, Resolve_UTF16) {
|
497
|
+
typedef GenericValue<UTF16<> > Value16;
|
498
|
+
typedef GenericUri<Value16> UriType;
|
499
|
+
CrtAllocator allocator;
|
500
|
+
|
501
|
+
// ref is full uri
|
502
|
+
UriType base = UriType(L"http://auth/path/#frag");
|
503
|
+
UriType ref = UriType(L"http://newauth/newpath#newfrag");
|
504
|
+
UriType res = ref.Resolve(base);
|
505
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://newauth/newpath#newfrag") == 0);
|
506
|
+
|
507
|
+
base = UriType(L"/path/#frag");
|
508
|
+
ref = UriType(L"http://newauth/newpath#newfrag");
|
509
|
+
res = ref.Resolve(base);
|
510
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://newauth/newpath#newfrag") == 0);
|
511
|
+
|
512
|
+
// ref is alternate uri
|
513
|
+
base = UriType(L"http://auth/path/#frag");
|
514
|
+
ref = UriType(L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f");
|
515
|
+
res = ref.Resolve(base);
|
516
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
517
|
+
|
518
|
+
// ref is absolute path
|
519
|
+
base = UriType(L"http://auth/path/#");
|
520
|
+
ref = UriType(L"/newpath#newfrag");
|
521
|
+
res = ref.Resolve(base);
|
522
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/newpath#newfrag") == 0);
|
523
|
+
|
524
|
+
// ref is relative path
|
525
|
+
base = UriType(L"http://auth/path/file.json#frag");
|
526
|
+
ref = UriType(L"newfile.json#");
|
527
|
+
res = ref.Resolve(base);
|
528
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/path/newfile.json#") == 0);
|
529
|
+
|
530
|
+
base = UriType(L"http://auth/path/file.json#frag/stuff");
|
531
|
+
ref = UriType(L"newfile.json#newfrag/newstuff");
|
532
|
+
res = ref.Resolve(base);
|
533
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/path/newfile.json#newfrag/newstuff") == 0);
|
534
|
+
|
535
|
+
base = UriType(L"file.json", &allocator);
|
536
|
+
ref = UriType(L"newfile.json", &base.GetAllocator());
|
537
|
+
res = ref.Resolve(base, &ref.GetAllocator());
|
538
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0);
|
539
|
+
|
540
|
+
base = UriType(L"file.json", &allocator);
|
541
|
+
ref = UriType(L"./newfile.json", &allocator);
|
542
|
+
res = ref.Resolve(base, &allocator);
|
543
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0);
|
544
|
+
|
545
|
+
base = UriType(L"file.json");
|
546
|
+
ref = UriType(L"parent/../newfile.json");
|
547
|
+
res = ref.Resolve(base);
|
548
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0);
|
549
|
+
|
550
|
+
base = UriType(L"file.json");
|
551
|
+
ref = UriType(L"parent/./newfile.json");
|
552
|
+
res = ref.Resolve(base);
|
553
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"parent/newfile.json") == 0);
|
554
|
+
|
555
|
+
base = UriType(L"file.json");
|
556
|
+
ref = UriType(L"../../parent/.././newfile.json");
|
557
|
+
res = ref.Resolve(base);
|
558
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"newfile.json") == 0);
|
559
|
+
|
560
|
+
// This adds a joining slash so resolved length is base length + ref length + 1
|
561
|
+
base = UriType(L"http://auth");
|
562
|
+
ref = UriType(L"newfile.json");
|
563
|
+
res = ref.Resolve(base);
|
564
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://auth/newfile.json") == 0);
|
565
|
+
|
566
|
+
// ref is fragment
|
567
|
+
base = UriType(L"#frag/stuff");
|
568
|
+
ref = UriType(L"#newfrag/newstuff");
|
569
|
+
res = ref.Resolve(base);
|
570
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"#newfrag/newstuff") == 0);
|
571
|
+
|
572
|
+
// test ref fragment always wins
|
573
|
+
base = UriType(L"/path#frag");
|
574
|
+
ref = UriType(L"");
|
575
|
+
res = ref.Resolve(base);
|
576
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"/path") == 0);
|
577
|
+
|
578
|
+
// Examples from RFC3896
|
579
|
+
base = UriType(L"http://a/b/c/d;p?q");
|
580
|
+
ref = UriType(L"g:h");
|
581
|
+
res = ref.Resolve(base);
|
582
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"g:h") == 0);
|
583
|
+
ref = UriType(L"g");
|
584
|
+
res = ref.Resolve(base);
|
585
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g") == 0);
|
586
|
+
ref = UriType(L"./g");
|
587
|
+
res = ref.Resolve(base);
|
588
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g") == 0);
|
589
|
+
ref = UriType(L"g/");
|
590
|
+
res = ref.Resolve(base);
|
591
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g/") == 0);
|
592
|
+
ref = UriType(L"/g");
|
593
|
+
res = ref.Resolve(base);
|
594
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0);
|
595
|
+
ref = UriType(L"//g");
|
596
|
+
res = ref.Resolve(base);
|
597
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://g") == 0);
|
598
|
+
ref = UriType(L"?y");
|
599
|
+
res = ref.Resolve(base);
|
600
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/d;p?y") == 0);
|
601
|
+
ref = UriType(L"g?y");
|
602
|
+
res = ref.Resolve(base);
|
603
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g?y") == 0);
|
604
|
+
ref = UriType(L"#s");
|
605
|
+
res = ref.Resolve(base);
|
606
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/d;p?q#s") == 0);
|
607
|
+
ref = UriType(L"g#s");
|
608
|
+
res = ref.Resolve(base);
|
609
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g#s") == 0);
|
610
|
+
ref = UriType(L"g?y#s");
|
611
|
+
res = ref.Resolve(base);
|
612
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g?y#s") == 0);
|
613
|
+
ref = UriType(L";x");
|
614
|
+
res = ref.Resolve(base);
|
615
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/;x") == 0);
|
616
|
+
ref = UriType(L"g;x");
|
617
|
+
res = ref.Resolve(base);
|
618
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g;x") == 0);
|
619
|
+
ref = UriType(L"g;x?y#s");
|
620
|
+
res = ref.Resolve(base);
|
621
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g;x?y#s") == 0);
|
622
|
+
ref = UriType(L"");
|
623
|
+
res = ref.Resolve(base);
|
624
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/d;p?q") == 0);
|
625
|
+
ref = UriType(L".");
|
626
|
+
res = ref.Resolve(base);
|
627
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/") == 0);
|
628
|
+
ref = UriType(L"./");
|
629
|
+
res = ref.Resolve(base);
|
630
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/") == 0);
|
631
|
+
ref = UriType(L"..");
|
632
|
+
res = ref.Resolve(base);
|
633
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/") == 0);
|
634
|
+
ref = UriType(L"../");
|
635
|
+
res = ref.Resolve(base);
|
636
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/") == 0);
|
637
|
+
ref = UriType(L"../g");
|
638
|
+
res = ref.Resolve(base);
|
639
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/g") == 0);
|
640
|
+
ref = UriType(L"../..");
|
641
|
+
res = ref.Resolve(base);
|
642
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/") == 0);
|
643
|
+
ref = UriType(L"../../");
|
644
|
+
res = ref.Resolve(base);
|
645
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/") == 0);
|
646
|
+
ref = UriType(L"../../g");
|
647
|
+
res = ref.Resolve(base);
|
648
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0);
|
649
|
+
ref = UriType(L"../../../g");
|
650
|
+
res = ref.Resolve(base);
|
651
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0);
|
652
|
+
ref = UriType(L"../../../../g");
|
653
|
+
res = ref.Resolve(base);
|
654
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0);
|
655
|
+
ref = UriType(L"/./g");
|
656
|
+
res = ref.Resolve(base);
|
657
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0);
|
658
|
+
ref = UriType(L"/../g");
|
659
|
+
res = ref.Resolve(base);
|
660
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/g") == 0);
|
661
|
+
ref = UriType(L"g.");
|
662
|
+
res = ref.Resolve(base);
|
663
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g.") == 0);
|
664
|
+
ref = UriType(L".g");
|
665
|
+
res = ref.Resolve(base);
|
666
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/.g") == 0);
|
667
|
+
ref = UriType(L"g..");
|
668
|
+
res = ref.Resolve(base);
|
669
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g..") == 0);
|
670
|
+
ref = UriType(L"..g");
|
671
|
+
res = ref.Resolve(base);
|
672
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/..g") == 0);
|
673
|
+
ref = UriType(L"g#s/../x");
|
674
|
+
res = ref.Resolve(base);
|
675
|
+
EXPECT_TRUE(StrCmp(res.GetString(), L"http://a/b/c/g#s/../x") == 0);
|
676
|
+
}
|
677
|
+
|
678
|
+
TEST(Uri, Equals) {
|
679
|
+
typedef GenericUri<Value> UriType;
|
680
|
+
|
681
|
+
UriType a = UriType("http://a/a#a");
|
682
|
+
UriType b = UriType("http://a/a#b");
|
683
|
+
UriType c = a;
|
684
|
+
|
685
|
+
EXPECT_TRUE(a == a);
|
686
|
+
EXPECT_TRUE(a == c);
|
687
|
+
EXPECT_TRUE(a != b);
|
688
|
+
}
|
689
|
+
|
690
|
+
TEST(Uri, Match) {
|
691
|
+
typedef GenericUri<Value> UriType;
|
692
|
+
|
693
|
+
UriType a = UriType("http://a/a#a");
|
694
|
+
UriType b = UriType("http://a/a#b");
|
695
|
+
UriType c = a;
|
696
|
+
UriType d;
|
697
|
+
|
698
|
+
EXPECT_TRUE(a.Match(a));
|
699
|
+
EXPECT_TRUE(a.Match(c));
|
700
|
+
EXPECT_FALSE(a.Match(b));
|
701
|
+
EXPECT_FALSE(a.Match(b, true));
|
702
|
+
EXPECT_TRUE(a.Match(b, false)); // Base Uri same
|
703
|
+
EXPECT_FALSE(a.Match(d));
|
704
|
+
EXPECT_FALSE(d.Match(a));
|
705
|
+
}
|
706
|
+
|
707
|
+
TEST(Uri, Issue1899) {
|
708
|
+
typedef GenericUri<Value, MemoryPoolAllocator<> > UriType;
|
709
|
+
|
710
|
+
UriType base = UriType("http://auth/path/#frag");
|
711
|
+
UriType ref = UriType("http://newauth/newpath#newfrag");
|
712
|
+
UriType res = ref.Resolve(base);
|
713
|
+
EXPECT_TRUE(StrCmp(res.GetString(), "http://newauth/newpath#newfrag") == 0);
|
714
|
+
}
|
715
|
+
|
716
|
+
#if defined(_MSC_VER) || defined(__clang__)
|
717
|
+
RAPIDJSON_DIAG_POP
|
718
|
+
#endif
|