xref: /aosp_15_r20/system/extras/libjsonpb/verify/test.cpp (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #include <limits>
18*288bf522SAndroid Build Coastguard Worker 
19*288bf522SAndroid Build Coastguard Worker #include <sstream>
20*288bf522SAndroid Build Coastguard Worker 
21*288bf522SAndroid Build Coastguard Worker #include <gmock/gmock.h>
22*288bf522SAndroid Build Coastguard Worker #include <gtest/gtest.h>
23*288bf522SAndroid Build Coastguard Worker #include <json/writer.h>
24*288bf522SAndroid Build Coastguard Worker #include <jsonpb/jsonpb.h>
25*288bf522SAndroid Build Coastguard Worker #include <jsonpb/verify.h>
26*288bf522SAndroid Build Coastguard Worker 
27*288bf522SAndroid Build Coastguard Worker #include "test.pb.h"
28*288bf522SAndroid Build Coastguard Worker 
29*288bf522SAndroid Build Coastguard Worker using ::android::jsonpb::internal::FormatJson;
30*288bf522SAndroid Build Coastguard Worker using ::testing::ElementsAre;
31*288bf522SAndroid Build Coastguard Worker using ::testing::HasSubstr;
32*288bf522SAndroid Build Coastguard Worker 
33*288bf522SAndroid Build Coastguard Worker namespace android {
34*288bf522SAndroid Build Coastguard Worker namespace jsonpb {
35*288bf522SAndroid Build Coastguard Worker 
36*288bf522SAndroid Build Coastguard Worker // Unit tests for libjsonpbverify.
37*288bf522SAndroid Build Coastguard Worker 
38*288bf522SAndroid Build Coastguard Worker class LibJsonpbVerifyTest : public ::testing::Test {};
39*288bf522SAndroid Build Coastguard Worker 
40*288bf522SAndroid Build Coastguard Worker class JsonKeyTest : public LibJsonpbVerifyTest {
41*288bf522SAndroid Build Coastguard Worker  public:
42*288bf522SAndroid Build Coastguard Worker   template <typename T>
GetFieldJsonName(const std::string & field_name)43*288bf522SAndroid Build Coastguard Worker   std::string GetFieldJsonName(const std::string& field_name) {
44*288bf522SAndroid Build Coastguard Worker     return T{}.GetDescriptor()->FindFieldByName(field_name)->json_name();
45*288bf522SAndroid Build Coastguard Worker   }
46*288bf522SAndroid Build Coastguard Worker 
47*288bf522SAndroid Build Coastguard Worker   template <typename T>
TestParseOkWithUnknownKey(const std::string & field_name,const std::string & json_key)48*288bf522SAndroid Build Coastguard Worker   void TestParseOkWithUnknownKey(const std::string& field_name, const std::string& json_key) {
49*288bf522SAndroid Build Coastguard Worker     std::string json = "{\"" + json_key + "\": \"test\"}";
50*288bf522SAndroid Build Coastguard Worker     auto object = JsonStringToMessage<T>(json);
51*288bf522SAndroid Build Coastguard Worker     ASSERT_TRUE(object.ok()) << object.error();
52*288bf522SAndroid Build Coastguard Worker     EXPECT_EQ("test", object->GetReflection()->GetString(
53*288bf522SAndroid Build Coastguard Worker                           *object, object->GetDescriptor()->FindFieldByName(field_name)));
54*288bf522SAndroid Build Coastguard Worker     std::string error;
55*288bf522SAndroid Build Coastguard Worker     ASSERT_FALSE(AllFieldsAreKnown(*object, json, &error))
56*288bf522SAndroid Build Coastguard Worker         << "AllFieldsAreKnown should return false";
57*288bf522SAndroid Build Coastguard Worker     EXPECT_THAT(error, HasSubstr("unknown keys"));
58*288bf522SAndroid Build Coastguard Worker     EXPECT_THAT(error, HasSubstr(json_key));
59*288bf522SAndroid Build Coastguard Worker   }
60*288bf522SAndroid Build Coastguard Worker };
61*288bf522SAndroid Build Coastguard Worker 
TEST_F(JsonKeyTest,WithJsonNameOk)62*288bf522SAndroid Build Coastguard Worker TEST_F(JsonKeyTest, WithJsonNameOk) {
63*288bf522SAndroid Build Coastguard Worker   std::string json =
64*288bf522SAndroid Build Coastguard Worker       "{\n"
65*288bf522SAndroid Build Coastguard Worker       "    \"FOOBAR\": \"foo_bar\",\n"
66*288bf522SAndroid Build Coastguard Worker       "    \"BarBaz\": \"barBaz\",\n"
67*288bf522SAndroid Build Coastguard Worker       "    \"baz_qux\": \"BazQux\",\n"
68*288bf522SAndroid Build Coastguard Worker       "    \"quxQuux\": \"QUX_QUUX\"\n"
69*288bf522SAndroid Build Coastguard Worker       "\n}";
70*288bf522SAndroid Build Coastguard Worker   auto object = JsonStringToMessage<WithJsonName>(json);
71*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(object.ok()) << object.error();
72*288bf522SAndroid Build Coastguard Worker 
73*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("foo_bar", object->foo_bar());
74*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("barBaz", object->barbaz());
75*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("BazQux", object->bazqux());
76*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("QUX_QUUX", object->qux_quux());
77*288bf522SAndroid Build Coastguard Worker 
78*288bf522SAndroid Build Coastguard Worker   std::string error;
79*288bf522SAndroid Build Coastguard Worker   EXPECT_TRUE(AllFieldsAreKnown(*object, json, &error)) << error;
80*288bf522SAndroid Build Coastguard Worker }
81*288bf522SAndroid Build Coastguard Worker 
82*288bf522SAndroid Build Coastguard Worker // If Prototype field name as keys while json_name is present, AllFieldsAreKnown
83*288bf522SAndroid Build Coastguard Worker // should return false.
TEST_F(JsonKeyTest,WithJsonNameFooBar)84*288bf522SAndroid Build Coastguard Worker TEST_F(JsonKeyTest, WithJsonNameFooBar) {
85*288bf522SAndroid Build Coastguard Worker   TestParseOkWithUnknownKey<WithJsonName>("foo_bar", "foo_bar");
86*288bf522SAndroid Build Coastguard Worker }
87*288bf522SAndroid Build Coastguard Worker 
TEST_F(JsonKeyTest,WithJsonNameBarBaz)88*288bf522SAndroid Build Coastguard Worker TEST_F(JsonKeyTest, WithJsonNameBarBaz) {
89*288bf522SAndroid Build Coastguard Worker   TestParseOkWithUnknownKey<WithJsonName>("barBaz", "barBaz");
90*288bf522SAndroid Build Coastguard Worker }
91*288bf522SAndroid Build Coastguard Worker 
TEST_F(JsonKeyTest,WithJsonNameBazQux)92*288bf522SAndroid Build Coastguard Worker TEST_F(JsonKeyTest, WithJsonNameBazQux) {
93*288bf522SAndroid Build Coastguard Worker   TestParseOkWithUnknownKey<WithJsonName>("BazQux", "BazQux");
94*288bf522SAndroid Build Coastguard Worker }
95*288bf522SAndroid Build Coastguard Worker 
TEST_F(JsonKeyTest,WithJsonNameQuxQuux)96*288bf522SAndroid Build Coastguard Worker TEST_F(JsonKeyTest, WithJsonNameQuxQuux) {
97*288bf522SAndroid Build Coastguard Worker   TestParseOkWithUnknownKey<WithJsonName>("QUX_QUUX", "QUX_QUUX");
98*288bf522SAndroid Build Coastguard Worker }
99*288bf522SAndroid Build Coastguard Worker 
100*288bf522SAndroid Build Coastguard Worker // JSON field name matches Proto field name
TEST_F(JsonKeyTest,NoJsonNameOk)101*288bf522SAndroid Build Coastguard Worker TEST_F(JsonKeyTest, NoJsonNameOk) {
102*288bf522SAndroid Build Coastguard Worker   std::string json =
103*288bf522SAndroid Build Coastguard Worker       "{\n"
104*288bf522SAndroid Build Coastguard Worker       "    \"foo_bar\": \"foo_bar\",\n"
105*288bf522SAndroid Build Coastguard Worker       "    \"barBaz\": \"barBaz\",\n"
106*288bf522SAndroid Build Coastguard Worker       "    \"BazQux\": \"BazQux\",\n"
107*288bf522SAndroid Build Coastguard Worker       "    \"QUX_QUUX\": \"QUX_QUUX\"\n"
108*288bf522SAndroid Build Coastguard Worker       "\n}";
109*288bf522SAndroid Build Coastguard Worker   auto object = JsonStringToMessage<NoJsonName>(json);
110*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(object.ok()) << object.error();
111*288bf522SAndroid Build Coastguard Worker 
112*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("foo_bar", object->foo_bar());
113*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("barBaz", object->barbaz());
114*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("BazQux", object->bazqux());
115*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("QUX_QUUX", object->qux_quux());
116*288bf522SAndroid Build Coastguard Worker 
117*288bf522SAndroid Build Coastguard Worker   std::string error;
118*288bf522SAndroid Build Coastguard Worker   EXPECT_TRUE(AllFieldsAreKnown(*object, json, &error)) << error;
119*288bf522SAndroid Build Coastguard Worker }
120*288bf522SAndroid Build Coastguard Worker 
121*288bf522SAndroid Build Coastguard Worker // JSON field name is lower/UpperCamelCase of Proto field name;
122*288bf522SAndroid Build Coastguard Worker // AllFieldsAreKnown should return false. Although the lower/UpperCamelCase name
123*288bf522SAndroid Build Coastguard Worker // is a valid key accepted by Protobuf's JSON parser, we explicitly disallow the
124*288bf522SAndroid Build Coastguard Worker // behavior.
TEST_F(JsonKeyTest,NoJsonNameFooBar)125*288bf522SAndroid Build Coastguard Worker TEST_F(JsonKeyTest, NoJsonNameFooBar) {
126*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("fooBar", GetFieldJsonName<NoJsonName>("foo_bar"));
127*288bf522SAndroid Build Coastguard Worker   TestParseOkWithUnknownKey<NoJsonName>("foo_bar", "fooBar");
128*288bf522SAndroid Build Coastguard Worker }
129*288bf522SAndroid Build Coastguard Worker 
TEST_F(JsonKeyTest,NoJsonNameBarBaz)130*288bf522SAndroid Build Coastguard Worker TEST_F(JsonKeyTest, NoJsonNameBarBaz) {
131*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("barBaz", GetFieldJsonName<NoJsonName>("barBaz"));
132*288bf522SAndroid Build Coastguard Worker   // No test for barBaz because its JSON name is the same as field_name
133*288bf522SAndroid Build Coastguard Worker }
134*288bf522SAndroid Build Coastguard Worker 
TEST_F(JsonKeyTest,NoJsonNameBazQux)135*288bf522SAndroid Build Coastguard Worker TEST_F(JsonKeyTest, NoJsonNameBazQux) {
136*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("BazQux", GetFieldJsonName<NoJsonName>("BazQux"));
137*288bf522SAndroid Build Coastguard Worker   // No test for BazQux because its JSON name is the same as field_name
138*288bf522SAndroid Build Coastguard Worker }
139*288bf522SAndroid Build Coastguard Worker 
TEST_F(JsonKeyTest,NoJsonNameQuxQuux)140*288bf522SAndroid Build Coastguard Worker TEST_F(JsonKeyTest, NoJsonNameQuxQuux) {
141*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("QUXQUUX", GetFieldJsonName<NoJsonName>("QUX_QUUX"));
142*288bf522SAndroid Build Coastguard Worker   TestParseOkWithUnknownKey<NoJsonName>("QUX_QUUX", "QUXQUUX");
143*288bf522SAndroid Build Coastguard Worker }
144*288bf522SAndroid Build Coastguard Worker 
145*288bf522SAndroid Build Coastguard Worker class EmbeddedJsonKeyTest : public LibJsonpbVerifyTest {
146*288bf522SAndroid Build Coastguard Worker  public:
TestEmbeddedError(const std::string & json,const std::string & unknown_key)147*288bf522SAndroid Build Coastguard Worker   ErrorOr<Parent> TestEmbeddedError(const std::string& json, const std::string& unknown_key) {
148*288bf522SAndroid Build Coastguard Worker     auto object = JsonStringToMessage<Parent>(json);
149*288bf522SAndroid Build Coastguard Worker     if (!object.ok()) return object;
150*288bf522SAndroid Build Coastguard Worker     std::string error;
151*288bf522SAndroid Build Coastguard Worker     EXPECT_FALSE(AllFieldsAreKnown(*object, json, &error))
152*288bf522SAndroid Build Coastguard Worker         << "AllFieldsAreKnown should return false";
153*288bf522SAndroid Build Coastguard Worker     EXPECT_THAT(error, HasSubstr("unknown keys"));
154*288bf522SAndroid Build Coastguard Worker     EXPECT_THAT(error, HasSubstr(unknown_key));
155*288bf522SAndroid Build Coastguard Worker     return object;
156*288bf522SAndroid Build Coastguard Worker   }
157*288bf522SAndroid Build Coastguard Worker };
158*288bf522SAndroid Build Coastguard Worker 
TEST_F(EmbeddedJsonKeyTest,Ok)159*288bf522SAndroid Build Coastguard Worker TEST_F(EmbeddedJsonKeyTest, Ok) {
160*288bf522SAndroid Build Coastguard Worker   std::string json =
161*288bf522SAndroid Build Coastguard Worker       "{"
162*288bf522SAndroid Build Coastguard Worker       "    \"with_json_name\": {\"FOOBAR\": \"foo_bar\"},\n"
163*288bf522SAndroid Build Coastguard Worker       "    \"repeated_with_json_name\": [{\"BarBaz\": \"barBaz\"}],\n"
164*288bf522SAndroid Build Coastguard Worker       "    \"no_json_name\": {\"BazQux\": \"BazQux\"},\n"
165*288bf522SAndroid Build Coastguard Worker       "    \"repeated_no_json_name\": [{\"QUX_QUUX\": \"QUX_QUUX\"}]\n"
166*288bf522SAndroid Build Coastguard Worker       "}";
167*288bf522SAndroid Build Coastguard Worker   auto object = JsonStringToMessage<Parent>(json);
168*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(object.ok()) << object.error();
169*288bf522SAndroid Build Coastguard Worker 
170*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("foo_bar", object->with_json_name().foo_bar());
171*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(1u, object->repeated_with_json_name().size());
172*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("barBaz", object->repeated_with_json_name().begin()->barbaz());
173*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("BazQux", object->no_json_name().bazqux());
174*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(1u, object->repeated_no_json_name().size());
175*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("QUX_QUUX", object->repeated_no_json_name().begin()->qux_quux());
176*288bf522SAndroid Build Coastguard Worker 
177*288bf522SAndroid Build Coastguard Worker   std::string error;
178*288bf522SAndroid Build Coastguard Worker   EXPECT_TRUE(AllFieldsAreKnown(*object, json, &error)) << error;
179*288bf522SAndroid Build Coastguard Worker }
180*288bf522SAndroid Build Coastguard Worker 
TEST_F(EmbeddedJsonKeyTest,FooBar)181*288bf522SAndroid Build Coastguard Worker TEST_F(EmbeddedJsonKeyTest, FooBar) {
182*288bf522SAndroid Build Coastguard Worker   auto object = TestEmbeddedError("{\"with_json_name\": {\"foo_bar\": \"test\"}}", "foo_bar");
183*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(object.ok()) << object.error();
184*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("test", object->with_json_name().foo_bar());
185*288bf522SAndroid Build Coastguard Worker }
186*288bf522SAndroid Build Coastguard Worker 
TEST_F(EmbeddedJsonKeyTest,BarBaz)187*288bf522SAndroid Build Coastguard Worker TEST_F(EmbeddedJsonKeyTest, BarBaz) {
188*288bf522SAndroid Build Coastguard Worker   auto object =
189*288bf522SAndroid Build Coastguard Worker       TestEmbeddedError("{\"repeated_with_json_name\": [{\"barBaz\": \"test\"}]}", "barBaz");
190*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(object.ok()) << object.error();
191*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(1u, object->repeated_with_json_name().size());
192*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("test", object->repeated_with_json_name().begin()->barbaz());
193*288bf522SAndroid Build Coastguard Worker }
194*288bf522SAndroid Build Coastguard Worker 
TEST_F(EmbeddedJsonKeyTest,NoJsonName)195*288bf522SAndroid Build Coastguard Worker TEST_F(EmbeddedJsonKeyTest, NoJsonName) {
196*288bf522SAndroid Build Coastguard Worker   auto object = TestEmbeddedError("{\"no_json_name\": {\"QUXQUUX\": \"test\"}}", "QUXQUUX");
197*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(object.ok()) << object.error();
198*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("test", object->no_json_name().qux_quux());
199*288bf522SAndroid Build Coastguard Worker }
200*288bf522SAndroid Build Coastguard Worker 
TEST_F(EmbeddedJsonKeyTest,QuxQuux)201*288bf522SAndroid Build Coastguard Worker TEST_F(EmbeddedJsonKeyTest, QuxQuux) {
202*288bf522SAndroid Build Coastguard Worker   auto object =
203*288bf522SAndroid Build Coastguard Worker       TestEmbeddedError("{\"repeated_no_json_name\": [{\"QUXQUUX\": \"test\"}]}", "QUXQUUX");
204*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(object.ok()) << object.error();
205*288bf522SAndroid Build Coastguard Worker   ASSERT_EQ(1u, object->repeated_no_json_name().size());
206*288bf522SAndroid Build Coastguard Worker   EXPECT_EQ("test", object->repeated_no_json_name().begin()->qux_quux());
207*288bf522SAndroid Build Coastguard Worker }
208*288bf522SAndroid Build Coastguard Worker 
209*288bf522SAndroid Build Coastguard Worker class ScalarTest : public LibJsonpbVerifyTest {
210*288bf522SAndroid Build Coastguard Worker  public:
IsJsonEq(const std::string & l,const std::string & r)211*288bf522SAndroid Build Coastguard Worker   ::testing::AssertionResult IsJsonEq(const std::string& l, const std::string& r) {
212*288bf522SAndroid Build Coastguard Worker     Json::CharReaderBuilder builder;
213*288bf522SAndroid Build Coastguard Worker     std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
214*288bf522SAndroid Build Coastguard Worker     Json::Value lvalue;
215*288bf522SAndroid Build Coastguard Worker     std::string errorMessage;
216*288bf522SAndroid Build Coastguard Worker     if (!reader->parse(&*l.begin(), &*l.end(), &lvalue, &errorMessage))
217*288bf522SAndroid Build Coastguard Worker       return ::testing::AssertionFailure() << errorMessage;
218*288bf522SAndroid Build Coastguard Worker     Json::Value rvalue;
219*288bf522SAndroid Build Coastguard Worker     if (!reader->parse(&*r.begin(), &*r.end(), &rvalue, &errorMessage))
220*288bf522SAndroid Build Coastguard Worker       return ::testing::AssertionFailure() << errorMessage;
221*288bf522SAndroid Build Coastguard Worker     Json::StreamWriterBuilder factory;
222*288bf522SAndroid Build Coastguard Worker     return lvalue == rvalue
223*288bf522SAndroid Build Coastguard Worker                ? (::testing::AssertionSuccess() << "Both are \n"
224*288bf522SAndroid Build Coastguard Worker                                                 << Json::writeString(factory, lvalue))
225*288bf522SAndroid Build Coastguard Worker                : (::testing::AssertionFailure() << Json::writeString(factory, lvalue)
226*288bf522SAndroid Build Coastguard Worker                                                 << "\n does not equal \n"
227*288bf522SAndroid Build Coastguard Worker                                                 << Json::writeString(factory, rvalue));
228*288bf522SAndroid Build Coastguard Worker   }
229*288bf522SAndroid Build Coastguard Worker 
EqReformattedJson(const std::string & json,std::string * error)230*288bf522SAndroid Build Coastguard Worker   bool EqReformattedJson(const std::string& json, std::string* error) {
231*288bf522SAndroid Build Coastguard Worker     return android::jsonpb::EqReformattedJson(json, &scalar_, error);
232*288bf522SAndroid Build Coastguard Worker   }
233*288bf522SAndroid Build Coastguard Worker 
234*288bf522SAndroid Build Coastguard Worker   Scalar scalar_;
235*288bf522SAndroid Build Coastguard Worker   std::string error_;
236*288bf522SAndroid Build Coastguard Worker };
237*288bf522SAndroid Build Coastguard Worker 
TEST_F(ScalarTest,Ok)238*288bf522SAndroid Build Coastguard Worker TEST_F(ScalarTest, Ok) {
239*288bf522SAndroid Build Coastguard Worker   std::string json =
240*288bf522SAndroid Build Coastguard Worker       "{\n"
241*288bf522SAndroid Build Coastguard Worker       "    \"i32\": 1,\n"
242*288bf522SAndroid Build Coastguard Worker       "    \"si32\": 1,\n"
243*288bf522SAndroid Build Coastguard Worker       "    \"i64\": \"1\",\n"
244*288bf522SAndroid Build Coastguard Worker       "    \"si64\": \"1\",\n"
245*288bf522SAndroid Build Coastguard Worker       "    \"f\": 1.5,\n"
246*288bf522SAndroid Build Coastguard Worker       "    \"d\": 1.5,\n"
247*288bf522SAndroid Build Coastguard Worker       "    \"e\": \"FOO\"\n"
248*288bf522SAndroid Build Coastguard Worker       "}";
249*288bf522SAndroid Build Coastguard Worker   auto formatted = FormatJson(json, &scalar_);
250*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(formatted.ok()) << formatted.error();
251*288bf522SAndroid Build Coastguard Worker   EXPECT_TRUE(IsJsonEq(json, *formatted));
252*288bf522SAndroid Build Coastguard Worker 
253*288bf522SAndroid Build Coastguard Worker   EXPECT_TRUE(EqReformattedJson(json, &error_)) << error_;
254*288bf522SAndroid Build Coastguard Worker }
255*288bf522SAndroid Build Coastguard Worker 
256*288bf522SAndroid Build Coastguard Worker using ScalarTestErrorParam = std::tuple<const char*, const char*>;
257*288bf522SAndroid Build Coastguard Worker class ScalarTestError : public ScalarTest,
258*288bf522SAndroid Build Coastguard Worker                         public ::testing::WithParamInterface<ScalarTestErrorParam> {};
259*288bf522SAndroid Build Coastguard Worker 
TEST_P(ScalarTestError,Test)260*288bf522SAndroid Build Coastguard Worker TEST_P(ScalarTestError, Test) {
261*288bf522SAndroid Build Coastguard Worker   std::string json;
262*288bf522SAndroid Build Coastguard Worker   std::string message;
263*288bf522SAndroid Build Coastguard Worker   std::tie(json, message) = GetParam();
264*288bf522SAndroid Build Coastguard Worker   auto formatted = FormatJson(json, &scalar_);
265*288bf522SAndroid Build Coastguard Worker   ASSERT_TRUE(formatted.ok()) << formatted.error();
266*288bf522SAndroid Build Coastguard Worker   EXPECT_FALSE(IsJsonEq(json, *formatted)) << message;
267*288bf522SAndroid Build Coastguard Worker   EXPECT_FALSE(EqReformattedJson(json, &error_)) << "EqReformattedJson should return false";
268*288bf522SAndroid Build Coastguard Worker }
269*288bf522SAndroid Build Coastguard Worker 
270*288bf522SAndroid Build Coastguard Worker static const std::vector<ScalarTestErrorParam> gScalarTestErrorParams = {
271*288bf522SAndroid Build Coastguard Worker     {"{\"i32\": \"1\"}", "Should not allow int32 values to be quoted"},
272*288bf522SAndroid Build Coastguard Worker     {"{\"si32\": \"1\"}", "Should not allow sint32 values to be quoted"},
273*288bf522SAndroid Build Coastguard Worker     {"{\"i64\": 1}", "Should require int64 values to be quoted"},
274*288bf522SAndroid Build Coastguard Worker     {"{\"si64\": 1}", "Should require sint64 values to be quoted"},
275*288bf522SAndroid Build Coastguard Worker     {"{\"f\": \"1.5\"}", "Should not allow float values to be quoted"},
276*288bf522SAndroid Build Coastguard Worker     {"{\"d\": \"1.5\"}", "Should not allow double values to be quoted"},
277*288bf522SAndroid Build Coastguard Worker     {"{\"e\": 1}", "Should not allow integers for enums"},
278*288bf522SAndroid Build Coastguard Worker };
279*288bf522SAndroid Build Coastguard Worker 
280*288bf522SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(Jsonpb, ScalarTestError, ::testing::ValuesIn(gScalarTestErrorParams));
281*288bf522SAndroid Build Coastguard Worker 
main(int argc,char ** argv)282*288bf522SAndroid Build Coastguard Worker int main(int argc, char** argv) {
283*288bf522SAndroid Build Coastguard Worker   using ::testing::AddGlobalTestEnvironment;
284*288bf522SAndroid Build Coastguard Worker   using ::testing::InitGoogleTest;
285*288bf522SAndroid Build Coastguard Worker 
286*288bf522SAndroid Build Coastguard Worker   InitGoogleTest(&argc, argv);
287*288bf522SAndroid Build Coastguard Worker   return RUN_ALL_TESTS();
288*288bf522SAndroid Build Coastguard Worker }
289*288bf522SAndroid Build Coastguard Worker 
290*288bf522SAndroid Build Coastguard Worker }  // namespace jsonpb
291*288bf522SAndroid Build Coastguard Worker }  // namespace android
292