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