| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- // Protocol Buffers - Google's data interchange format
- // Copyright 2008 Google Inc. All rights reserved.
- // https://developers.google.com/protocol-buffers/
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #include <google/protobuf/util/internal/json_objectwriter.h>
- #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
- #include <google/protobuf/util/internal/utility.h>
- #include <gtest/gtest.h>
- namespace google {
- namespace protobuf {
- namespace util {
- namespace converter {
- using google::protobuf::io::CodedOutputStream;
- using google::protobuf::io::StringOutputStream;
- class JsonObjectWriterTest : public ::testing::Test {
- protected:
- JsonObjectWriterTest()
- : str_stream_(new StringOutputStream(&output_)),
- out_stream_(new CodedOutputStream(str_stream_)),
- ow_(nullptr) {}
- virtual ~JsonObjectWriterTest() {
- delete ow_;
- delete out_stream_;
- delete str_stream_;
- }
- string output_;
- StringOutputStream* const str_stream_;
- CodedOutputStream* const out_stream_;
- JsonObjectWriter* ow_;
- };
- TEST_F(JsonObjectWriterTest, EmptyRootObject) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")->EndObject();
- EXPECT_EQ("{}", output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, EmptyObject) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")
- ->RenderString("test", "value")
- ->StartObject("empty")
- ->EndObject()
- ->EndObject();
- EXPECT_EQ("{\"test\":\"value\",\"empty\":{}}",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, EmptyRootList) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartList("")->EndList();
- EXPECT_EQ("[]", output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, EmptyList) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")
- ->RenderString("test", "value")
- ->StartList("empty")
- ->EndList()
- ->EndObject();
- EXPECT_EQ("{\"test\":\"value\",\"empty\":[]}",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, EmptyObjectKey) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")->RenderString("", "value")->EndObject();
- EXPECT_EQ("{\"\":\"value\"}", output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, ObjectInObject) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")
- ->StartObject("nested")
- ->RenderString("field", "value")
- ->EndObject()
- ->EndObject();
- EXPECT_EQ("{\"nested\":{\"field\":\"value\"}}",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, ListInObject) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")
- ->StartList("nested")
- ->RenderString("", "value")
- ->EndList()
- ->EndObject();
- EXPECT_EQ("{\"nested\":[\"value\"]}",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, ObjectInList) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartList("")
- ->StartObject("")
- ->RenderString("field", "value")
- ->EndObject()
- ->EndList();
- EXPECT_EQ("[{\"field\":\"value\"}]",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, ListInList) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartList("")
- ->StartList("")
- ->RenderString("", "value")
- ->EndList()
- ->EndList();
- EXPECT_EQ("[[\"value\"]]", output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, RenderPrimitives) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")
- ->RenderBool("bool", true)
- ->RenderDouble("double", std::numeric_limits<double>::max())
- ->RenderFloat("float", std::numeric_limits<float>::max())
- ->RenderInt32("int", std::numeric_limits<int32>::min())
- ->RenderInt64("long", std::numeric_limits<int64>::min())
- ->RenderBytes("bytes", "abracadabra")
- ->RenderString("string", "string")
- ->RenderBytes("emptybytes", "")
- ->RenderString("emptystring", string())
- ->EndObject();
- EXPECT_EQ(
- "{\"bool\":true,"
- "\"double\":" +
- ValueAsString<double>(std::numeric_limits<double>::max()) +
- ","
- "\"float\":" +
- ValueAsString<float>(std::numeric_limits<float>::max()) +
- ","
- "\"int\":-2147483648,"
- "\"long\":\"-9223372036854775808\","
- "\"bytes\":\"YWJyYWNhZGFicmE=\","
- "\"string\":\"string\","
- "\"emptybytes\":\"\","
- "\"emptystring\":\"\"}",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, BytesEncodesAsNonWebSafeBase64) {
- string s;
- s.push_back('\377');
- s.push_back('\357');
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")->RenderBytes("bytes", s)->EndObject();
- // Non-web-safe would encode this as "/+8="
- EXPECT_EQ("{\"bytes\":\"/+8=\"}",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, PrettyPrintList) {
- ow_ = new JsonObjectWriter(" ", out_stream_);
- ow_->StartObject("")
- ->StartList("items")
- ->RenderString("", "item1")
- ->RenderString("", "item2")
- ->RenderString("", "item3")
- ->EndList()
- ->StartList("empty")
- ->EndList()
- ->EndObject();
- EXPECT_EQ(
- "{\n"
- " \"items\": [\n"
- " \"item1\",\n"
- " \"item2\",\n"
- " \"item3\"\n"
- " ],\n"
- " \"empty\": []\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, PrettyPrintObject) {
- ow_ = new JsonObjectWriter(" ", out_stream_);
- ow_->StartObject("")
- ->StartObject("items")
- ->RenderString("key1", "item1")
- ->RenderString("key2", "item2")
- ->RenderString("key3", "item3")
- ->EndObject()
- ->StartObject("empty")
- ->EndObject()
- ->EndObject();
- EXPECT_EQ(
- "{\n"
- " \"items\": {\n"
- " \"key1\": \"item1\",\n"
- " \"key2\": \"item2\",\n"
- " \"key3\": \"item3\"\n"
- " },\n"
- " \"empty\": {}\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, PrettyPrintEmptyObjectInEmptyList) {
- ow_ = new JsonObjectWriter(" ", out_stream_);
- ow_->StartObject("")
- ->StartList("list")
- ->StartObject("")
- ->EndObject()
- ->EndList()
- ->EndObject();
- EXPECT_EQ(
- "{\n"
- " \"list\": [\n"
- " {}\n"
- " ]\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, PrettyPrintDoubleIndent) {
- ow_ = new JsonObjectWriter(" ", out_stream_);
- ow_->StartObject("")
- ->RenderBool("bool", true)
- ->RenderInt32("int", 42)
- ->EndObject();
- EXPECT_EQ(
- "{\n"
- " \"bool\": true,\n"
- " \"int\": 42\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, StringsEscapedAndEnclosedInDoubleQuotes) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")->RenderString("string", "'<>&\\\"\r\n")->EndObject();
- EXPECT_EQ("{\"string\":\"'\\u003c\\u003e&\\\\\\\"\\r\\n\"}",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, Stringification) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")
- ->RenderDouble("double_nan", std::numeric_limits<double>::quiet_NaN())
- ->RenderFloat("float_nan", std::numeric_limits<float>::quiet_NaN())
- ->RenderDouble("double_pos", std::numeric_limits<double>::infinity())
- ->RenderFloat("float_pos", std::numeric_limits<float>::infinity())
- ->RenderDouble("double_neg", -std::numeric_limits<double>::infinity())
- ->RenderFloat("float_neg", -std::numeric_limits<float>::infinity())
- ->EndObject();
- EXPECT_EQ(
- "{\"double_nan\":\"NaN\","
- "\"float_nan\":\"NaN\","
- "\"double_pos\":\"Infinity\","
- "\"float_pos\":\"Infinity\","
- "\"double_neg\":\"-Infinity\","
- "\"float_neg\":\"-Infinity\"}",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, TestRegularByteEncoding) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")
- ->RenderBytes("bytes", "\x03\xef\xc0")
- ->EndObject();
- // Test that we get regular (non websafe) base64 encoding on byte fields by
- // default.
- EXPECT_EQ("{\"bytes\":\"A+/A\"}",
- output_.substr(0, out_stream_->ByteCount()));
- }
- TEST_F(JsonObjectWriterTest, TestWebsafeByteEncoding) {
- ow_ = new JsonObjectWriter("", out_stream_);
- ow_->set_use_websafe_base64_for_bytes(true);
- ow_->StartObject("")
- ->RenderBytes("bytes", "\x03\xef\xc0\x10")
- ->EndObject();
- // Test that we get websafe base64 encoding when explicitly asked.
- EXPECT_EQ("{\"bytes\":\"A-_AEA==\"}",
- output_.substr(0, out_stream_->ByteCount()));
- }
- } // namespace converter
- } // namespace util
- } // namespace protobuf
- } // namespace google
|