123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- /*
- *
- * Copyright 2015-2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- #include "src/core/lib/json/json.h"
- #include <string.h>
- #include <gmock/gmock.h>
- #include <gtest/gtest.h>
- #include <grpc/support/alloc.h>
- #include <grpc/support/log.h>
- #include <grpc/support/string_util.h>
- #include "src/core/lib/gpr/string.h"
- #include "src/core/lib/gpr/useful.h"
- #include "test/core/util/test_config.h"
- namespace grpc_core {
- void ValidateValue(const Json& actual, const Json& expected);
- void ValidateObject(const Json::Object& actual, const Json::Object& expected) {
- ASSERT_EQ(actual.size(), expected.size());
- auto actual_it = actual.begin();
- for (const auto& p : expected) {
- EXPECT_EQ(actual_it->first, p.first);
- ValidateValue(actual_it->second, p.second);
- ++actual_it;
- }
- }
- void ValidateArray(const Json::Array& actual, const Json::Array& expected) {
- ASSERT_EQ(actual.size(), expected.size());
- for (size_t i = 0; i < expected.size(); ++i) {
- ValidateValue(actual[i], expected[i]);
- }
- }
- void ValidateValue(const Json& actual, const Json& expected) {
- ASSERT_EQ(actual.type(), expected.type());
- switch (expected.type()) {
- case Json::Type::JSON_NULL:
- case Json::Type::JSON_TRUE:
- case Json::Type::JSON_FALSE:
- break;
- case Json::Type::STRING:
- case Json::Type::NUMBER:
- EXPECT_EQ(actual.string_value(), expected.string_value());
- break;
- case Json::Type::OBJECT:
- ValidateObject(actual.object_value(), expected.object_value());
- break;
- case Json::Type::ARRAY:
- ValidateArray(actual.array_value(), expected.array_value());
- break;
- }
- }
- void RunSuccessTest(const char* input, const Json& expected,
- const char* expected_output) {
- gpr_log(GPR_INFO, "parsing string \"%s\" - should succeed", input);
- grpc_error_handle error = GRPC_ERROR_NONE;
- Json json = Json::Parse(input, &error);
- ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
- ValidateValue(json, expected);
- std::string output = json.Dump();
- EXPECT_EQ(output, expected_output);
- }
- TEST(Json, Whitespace) {
- RunSuccessTest(" 0 ", 0, "0");
- RunSuccessTest(" 1 ", 1, "1");
- RunSuccessTest(" \" \" ", " ", "\" \"");
- RunSuccessTest(" \"a\" ", "a", "\"a\"");
- RunSuccessTest(" true ", true, "true");
- }
- TEST(Json, Utf16) {
- RunSuccessTest("\"\\u0020\\\\\\u0010\\u000a\\u000D\"", " \\\u0010\n\r",
- "\" \\\\\\u0010\\n\\r\"");
- }
- TEST(Json, Utf8) {
- RunSuccessTest("\"ßâñć௵⇒\"", "ßâñć௵⇒",
- "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"");
- RunSuccessTest("\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"", "ßâñć௵⇒",
- "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"");
- // Testing UTF-8 character "𝄞", U+11D1E.
- RunSuccessTest("\"\xf0\x9d\x84\x9e\"", "\xf0\x9d\x84\x9e",
- "\"\\ud834\\udd1e\"");
- RunSuccessTest("\"\\ud834\\udd1e\"", "\xf0\x9d\x84\x9e",
- "\"\\ud834\\udd1e\"");
- RunSuccessTest("{\"\\ud834\\udd1e\":0}",
- Json::Object{{"\xf0\x9d\x84\x9e", 0}},
- "{\"\\ud834\\udd1e\":0}");
- }
- TEST(Json, NestedEmptyContainers) {
- RunSuccessTest(" [ [ ] , { } , [ ] ] ",
- Json::Array{
- Json::Array(),
- Json::Object(),
- Json::Array(),
- },
- "[[],{},[]]");
- }
- TEST(Json, EscapesAndControlCharactersInKeyStrings) {
- RunSuccessTest(" { \"\\u007f\x7f\\n\\r\\\"\\f\\b\\\\a , b\": 1, \"\": 0 } ",
- Json::Object{
- {"\u007f\u007f\n\r\"\f\b\\a , b", 1},
- {"", 0},
- },
- "{\"\":0,\"\\u007f\\u007f\\n\\r\\\"\\f\\b\\\\a , b\":1}");
- }
- TEST(Json, WriterCutsOffInvalidUtf8) {
- EXPECT_EQ(Json("abc\xf0\x9d\x24").Dump(), "\"abc\"");
- EXPECT_EQ(Json("\xff").Dump(), "\"\"");
- }
- TEST(Json, ValidNumbers) {
- RunSuccessTest("[0, 42 , 0.0123, 123.456]",
- Json::Array{
- 0,
- 42,
- Json("0.0123", /*is_number=*/true),
- Json("123.456", /*is_number=*/true),
- },
- "[0,42,0.0123,123.456]");
- RunSuccessTest("[1e4,-53.235e-31, 0.3e+3]",
- Json::Array{
- Json("1e4", /*is_number=*/true),
- Json("-53.235e-31", /*is_number=*/true),
- Json("0.3e+3", /*is_number=*/true),
- },
- "[1e4,-53.235e-31,0.3e+3]");
- }
- TEST(Json, Keywords) {
- RunSuccessTest("[true, false, null]",
- Json::Array{
- Json(true),
- Json(false),
- Json(),
- },
- "[true,false,null]");
- }
- void RunParseFailureTest(const char* input) {
- gpr_log(GPR_INFO, "parsing string \"%s\" - should fail", input);
- grpc_error_handle error = GRPC_ERROR_NONE;
- Json json = Json::Parse(input, &error);
- gpr_log(GPR_INFO, "error: %s", grpc_error_std_string(error).c_str());
- EXPECT_NE(error, GRPC_ERROR_NONE);
- GRPC_ERROR_UNREF(error);
- }
- TEST(Json, InvalidInput) {
- RunParseFailureTest("\\");
- RunParseFailureTest("nu ll");
- RunParseFailureTest("{\"foo\": bar}");
- RunParseFailureTest("{\"foo\": bar\"x\"}");
- RunParseFailureTest("fals");
- RunParseFailureTest("0,0 ");
- RunParseFailureTest("\"foo\",[]");
- }
- TEST(Json, UnterminatedString) { RunParseFailureTest("\"\\x"); }
- TEST(Json, InvalidUtf16) {
- RunParseFailureTest("\"\\u123x");
- RunParseFailureTest("{\"\\u123x");
- }
- TEST(Json, ImbalancedSurrogatePairs) {
- RunParseFailureTest("\"\\ud834f");
- RunParseFailureTest("{\"\\ud834f\":0}");
- RunParseFailureTest("\"\\ud834\\n");
- RunParseFailureTest("{\"\\ud834\\n\":0}");
- RunParseFailureTest("\"\\udd1ef");
- RunParseFailureTest("{\"\\udd1ef\":0}");
- RunParseFailureTest("\"\\ud834\\ud834\"");
- RunParseFailureTest("{\"\\ud834\\ud834\"\":0}");
- RunParseFailureTest("\"\\ud834\\u1234\"");
- RunParseFailureTest("{\"\\ud834\\u1234\"\":0}");
- RunParseFailureTest("\"\\ud834]\"");
- RunParseFailureTest("{\"\\ud834]\"\":0}");
- RunParseFailureTest("\"\\ud834 \"");
- RunParseFailureTest("{\"\\ud834 \"\":0}");
- RunParseFailureTest("\"\\ud834\\\\\"");
- RunParseFailureTest("{\"\\ud834\\\\\"\":0}");
- }
- TEST(Json, EmbeddedInvalidWhitechars) {
- RunParseFailureTest("\"\n\"");
- RunParseFailureTest("\"\t\"");
- }
- TEST(Json, EmptyString) { RunParseFailureTest(""); }
- TEST(Json, ExtraCharsAtEndOfParsing) {
- RunParseFailureTest("{},");
- RunParseFailureTest("{}x");
- }
- TEST(Json, ImbalancedContainers) {
- RunParseFailureTest("{}}");
- RunParseFailureTest("[]]");
- RunParseFailureTest("{{}");
- RunParseFailureTest("[[]");
- RunParseFailureTest("[}");
- RunParseFailureTest("{]");
- }
- TEST(Json, BadContainers) {
- RunParseFailureTest("{x}");
- RunParseFailureTest("{x=0,y}");
- }
- TEST(Json, DuplicateObjectKeys) { RunParseFailureTest("{\"x\": 1, \"x\": 1}"); }
- TEST(Json, TrailingComma) {
- RunParseFailureTest("{,}");
- RunParseFailureTest("[1,2,3,4,]");
- RunParseFailureTest("{\"a\": 1, }");
- }
- TEST(Json, KeySyntaxInArray) { RunParseFailureTest("[\"x\":0]"); }
- TEST(Json, InvalidNumbers) {
- RunParseFailureTest("1.");
- RunParseFailureTest("1e");
- RunParseFailureTest(".12");
- RunParseFailureTest("1.x");
- RunParseFailureTest("1.12x");
- RunParseFailureTest("1ex");
- RunParseFailureTest("1e12x");
- RunParseFailureTest(".12x");
- RunParseFailureTest("000");
- };
- TEST(Json, Equality) {
- // Null.
- EXPECT_EQ(Json(), Json());
- // Numbers.
- EXPECT_EQ(Json(1), Json(1));
- EXPECT_NE(Json(1), Json(2));
- EXPECT_EQ(Json(1), Json("1", /*is_number=*/true));
- EXPECT_EQ(Json("-5e5", /*is_number=*/true), Json("-5e5", /*is_number=*/true));
- // Booleans.
- EXPECT_EQ(Json(true), Json(true));
- EXPECT_EQ(Json(false), Json(false));
- EXPECT_NE(Json(true), Json(false));
- // Strings.
- EXPECT_EQ(Json("foo"), Json("foo"));
- EXPECT_NE(Json("foo"), Json("bar"));
- // Arrays.
- EXPECT_EQ(Json(Json::Array{"foo"}), Json(Json::Array{"foo"}));
- EXPECT_NE(Json(Json::Array{"foo"}), Json(Json::Array{"bar"}));
- // Objects.
- EXPECT_EQ(Json(Json::Object{{"foo", 1}}), Json(Json::Object{{"foo", 1}}));
- EXPECT_NE(Json(Json::Object{{"foo", 1}}), Json(Json::Object{{"foo", 2}}));
- EXPECT_NE(Json(Json::Object{{"foo", 1}}), Json(Json::Object{{"bar", 1}}));
- // Differing types.
- EXPECT_NE(Json(1), Json("foo"));
- EXPECT_NE(Json(1), Json(true));
- EXPECT_NE(Json(1), Json(Json::Array{}));
- EXPECT_NE(Json(1), Json(Json::Object{}));
- EXPECT_NE(Json(1), Json());
- }
- } // namespace grpc_core
- int main(int argc, char** argv) {
- grpc::testing::TestEnvironment env(argc, argv);
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
- }
|