• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #include "include/cef_parser.h"
6 #include "tests/gtest/include/gtest/gtest.h"
7 
8 // Create the URL using the spec.
TEST(ParserTest,CreateURLSpec)9 TEST(ParserTest, CreateURLSpec) {
10   CefURLParts parts;
11   CefString url;
12   CefString(&parts.spec)
13       .FromASCII(
14           "http://user:pass@www.example.com:88/path/"
15           "to.html?foo=test&bar=test2");
16   EXPECT_TRUE(CefCreateURL(parts, url));
17   EXPECT_STREQ(
18       "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2",
19       url.ToString().c_str());
20 }
21 
22 // Test that host is required.
TEST(ParserTest,CreateURLHostRequired)23 TEST(ParserTest, CreateURLHostRequired) {
24   CefURLParts parts;
25   CefString url;
26   CefString(&parts.scheme).FromASCII("http");
27   EXPECT_FALSE(CefCreateURL(parts, url));
28 }
29 
30 // Test that scheme is required.
TEST(ParserTest,CreateURLSchemeRequired)31 TEST(ParserTest, CreateURLSchemeRequired) {
32   CefURLParts parts;
33   CefString url;
34   CefString(&parts.host).FromASCII("www.example.com");
35   EXPECT_FALSE(CefCreateURL(parts, url));
36 }
37 
38 // Create the URL using scheme and host.
TEST(ParserTest,CreateURLSchemeHost)39 TEST(ParserTest, CreateURLSchemeHost) {
40   CefURLParts parts;
41   CefString url;
42   CefString(&parts.scheme).FromASCII("http");
43   CefString(&parts.host).FromASCII("www.example.com");
44   EXPECT_TRUE(CefCreateURL(parts, url));
45   EXPECT_STREQ("http://www.example.com/", url.ToString().c_str());
46 }
47 
48 // Create the URL using scheme, host and path.
TEST(ParserTest,CreateURLSchemeHostPath)49 TEST(ParserTest, CreateURLSchemeHostPath) {
50   CefURLParts parts;
51   CefString url;
52   CefString(&parts.scheme).FromASCII("http");
53   CefString(&parts.host).FromASCII("www.example.com");
54   CefString(&parts.path).FromASCII("/path/to.html");
55   EXPECT_TRUE(CefCreateURL(parts, url));
56   EXPECT_STREQ("http://www.example.com/path/to.html", url.ToString().c_str());
57 }
58 
59 // Create the URL using scheme, host, path and query.
TEST(ParserTest,CreateURLSchemeHostPathQuery)60 TEST(ParserTest, CreateURLSchemeHostPathQuery) {
61   CefURLParts parts;
62   CefString url;
63   CefString(&parts.scheme).FromASCII("http");
64   CefString(&parts.host).FromASCII("www.example.com");
65   CefString(&parts.path).FromASCII("/path/to.html");
66   CefString(&parts.query).FromASCII("foo=test&bar=test2");
67   EXPECT_TRUE(CefCreateURL(parts, url));
68   EXPECT_STREQ("http://www.example.com/path/to.html?foo=test&bar=test2",
69                url.ToString().c_str());
70 }
71 
72 // Create the URL using scheme, host, path, query and Fragment
TEST(ParserTest,CreateURLSchemeHostPathQueryFragment)73 TEST(ParserTest, CreateURLSchemeHostPathQueryFragment) {
74   CefURLParts parts;
75   CefString url;
76   CefString(&parts.scheme).FromASCII("http");
77   CefString(&parts.host).FromASCII("www.example.com");
78   CefString(&parts.path).FromASCII("/path/to.html");
79   CefString(&parts.query).FromASCII("foo=test&bar=test2");
80   CefString(&parts.fragment).FromASCII("ref");
81   EXPECT_TRUE(CefCreateURL(parts, url));
82   EXPECT_STREQ("http://www.example.com/path/to.html?foo=test&bar=test2#ref",
83                url.ToString().c_str());
84 }
85 
86 // Create the URL using all the various components.
TEST(ParserTest,CreateURLAll)87 TEST(ParserTest, CreateURLAll) {
88   CefURLParts parts;
89   CefString url;
90   CefString(&parts.scheme).FromASCII("http");
91   CefString(&parts.username).FromASCII("user");
92   CefString(&parts.password).FromASCII("pass");
93   CefString(&parts.host).FromASCII("www.example.com");
94   CefString(&parts.port).FromASCII("88");
95   CefString(&parts.path).FromASCII("/path/to.html");
96   CefString(&parts.query).FromASCII("foo=test&bar=test2");
97   CefString(&parts.fragment).FromASCII("ref");
98   EXPECT_TRUE(CefCreateURL(parts, url));
99   EXPECT_STREQ(
100       "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2#ref",
101       url.ToString().c_str());
102 }
103 
104 // Parse the URL using scheme and host.
TEST(ParserTest,ParseURLSchemeHost)105 TEST(ParserTest, ParseURLSchemeHost) {
106   CefURLParts parts;
107   CefString url;
108   url.FromASCII("http://www.example.com");
109   EXPECT_TRUE(CefParseURL(url, parts));
110 
111   CefString spec(&parts.spec);
112   EXPECT_STREQ("http://www.example.com/", spec.ToString().c_str());
113   EXPECT_EQ(0U, parts.username.length);
114   EXPECT_EQ(0U, parts.password.length);
115   CefString scheme(&parts.scheme);
116   EXPECT_STREQ("http", scheme.ToString().c_str());
117   CefString host(&parts.host);
118   EXPECT_STREQ("www.example.com", host.ToString().c_str());
119   EXPECT_EQ(0U, parts.port.length);
120   CefString origin(&parts.origin);
121   EXPECT_STREQ(origin.ToString().c_str(), "http://www.example.com/");
122   CefString path(&parts.path);
123   EXPECT_STREQ("/", path.ToString().c_str());
124   EXPECT_EQ(0U, parts.query.length);
125 }
126 
127 // Parse the URL using scheme, host and path.
TEST(ParserTest,ParseURLSchemeHostPath)128 TEST(ParserTest, ParseURLSchemeHostPath) {
129   CefURLParts parts;
130   CefString url;
131   url.FromASCII("http://www.example.com/path/to.html");
132   EXPECT_TRUE(CefParseURL(url, parts));
133 
134   CefString spec(&parts.spec);
135   EXPECT_STREQ("http://www.example.com/path/to.html", spec.ToString().c_str());
136   EXPECT_EQ(0U, parts.username.length);
137   EXPECT_EQ(0U, parts.password.length);
138   CefString scheme(&parts.scheme);
139   EXPECT_STREQ("http", scheme.ToString().c_str());
140   CefString host(&parts.host);
141   EXPECT_STREQ("www.example.com", host.ToString().c_str());
142   EXPECT_EQ(0U, parts.port.length);
143   CefString origin(&parts.origin);
144   EXPECT_STREQ(origin.ToString().c_str(), "http://www.example.com/");
145   CefString path(&parts.path);
146   EXPECT_STREQ("/path/to.html", path.ToString().c_str());
147   EXPECT_EQ(0U, parts.query.length);
148 }
149 
150 // Parse the URL using scheme, host, path and query.
TEST(ParserTest,ParseURLSchemeHostPathQuery)151 TEST(ParserTest, ParseURLSchemeHostPathQuery) {
152   CefURLParts parts;
153   CefString url;
154   url.FromASCII("http://www.example.com/path/to.html?foo=test&bar=test2");
155   EXPECT_TRUE(CefParseURL(url, parts));
156 
157   CefString spec(&parts.spec);
158   EXPECT_STREQ("http://www.example.com/path/to.html?foo=test&bar=test2",
159                spec.ToString().c_str());
160   EXPECT_EQ(0U, parts.username.length);
161   EXPECT_EQ(0U, parts.password.length);
162   CefString scheme(&parts.scheme);
163   EXPECT_STREQ("http", scheme.ToString().c_str());
164   CefString host(&parts.host);
165   EXPECT_STREQ("www.example.com", host.ToString().c_str());
166   EXPECT_EQ(0U, parts.port.length);
167   CefString origin(&parts.origin);
168   EXPECT_STREQ(origin.ToString().c_str(), "http://www.example.com/");
169   CefString path(&parts.path);
170   EXPECT_STREQ("/path/to.html", path.ToString().c_str());
171   CefString query(&parts.query);
172   EXPECT_STREQ("foo=test&bar=test2", query.ToString().c_str());
173 }
174 
175 // Parse the URL using scheme, host, path, query and fragment.
TEST(ParserTest,ParseURLSchemeHostPathQueryFragment)176 TEST(ParserTest, ParseURLSchemeHostPathQueryFragment) {
177   CefURLParts parts;
178   CefString url;
179   url.FromASCII("http://www.example.com/path/to.html?foo=test&bar=test2#ref");
180   EXPECT_TRUE(CefParseURL(url, parts));
181 
182   CefString spec(&parts.spec);
183   EXPECT_STREQ("http://www.example.com/path/to.html?foo=test&bar=test2#ref",
184                spec.ToString().c_str());
185   EXPECT_EQ(0U, parts.username.length);
186   EXPECT_EQ(0U, parts.password.length);
187   CefString scheme(&parts.scheme);
188   EXPECT_STREQ("http", scheme.ToString().c_str());
189   CefString host(&parts.host);
190   EXPECT_STREQ("www.example.com", host.ToString().c_str());
191   EXPECT_EQ(0U, parts.port.length);
192   CefString origin(&parts.origin);
193   EXPECT_STREQ(origin.ToString().c_str(), "http://www.example.com/");
194   CefString path(&parts.path);
195   EXPECT_STREQ("/path/to.html", path.ToString().c_str());
196   CefString query(&parts.query);
197   EXPECT_STREQ("foo=test&bar=test2", query.ToString().c_str());
198   CefString ref(&parts.fragment);
199   EXPECT_STREQ("ref", ref.ToString().c_str());
200 }
201 
202 // Parse the URL using all the various components.
TEST(ParserTest,ParseURLAll)203 TEST(ParserTest, ParseURLAll) {
204   CefURLParts parts;
205   CefString url;
206   url.FromASCII(
207       "http://user:pass@www.example.com:88/path/"
208       "to.html?foo=test&bar=test2#ref");
209   EXPECT_TRUE(CefParseURL(url, parts));
210 
211   CefString spec(&parts.spec);
212   EXPECT_STREQ(
213       "http://user:pass@www.example.com:88/path/to.html?foo=test&bar=test2#ref",
214       spec.ToString().c_str());
215   CefString scheme(&parts.scheme);
216   EXPECT_STREQ("http", scheme.ToString().c_str());
217   CefString username(&parts.username);
218   EXPECT_STREQ("user", username.ToString().c_str());
219   CefString password(&parts.password);
220   EXPECT_STREQ("pass", password.ToString().c_str());
221   CefString host(&parts.host);
222   EXPECT_STREQ("www.example.com", host.ToString().c_str());
223   CefString port(&parts.port);
224   EXPECT_STREQ("88", port.ToString().c_str());
225   CefString origin(&parts.origin);
226   EXPECT_STREQ(origin.ToString().c_str(), "http://www.example.com:88/");
227   CefString path(&parts.path);
228   EXPECT_STREQ("/path/to.html", path.ToString().c_str());
229   CefString query(&parts.query);
230   EXPECT_STREQ("foo=test&bar=test2", query.ToString().c_str());
231   CefString ref(&parts.fragment);
232   EXPECT_STREQ("ref", ref.ToString().c_str());
233 }
234 
235 // Parse an invalid URL.
TEST(ParserTest,ParseURLInvalid)236 TEST(ParserTest, ParseURLInvalid) {
237   CefURLParts parts;
238   CefString url;
239   url.FromASCII("www.example.com");
240   EXPECT_FALSE(CefParseURL(url, parts));
241 }
242 
243 // Parse a non-standard scheme.
TEST(ParserTest,ParseURLNonStandard)244 TEST(ParserTest, ParseURLNonStandard) {
245   CefURLParts parts;
246   CefString url;
247   url.FromASCII("custom:something%20else?foo#ref");
248   EXPECT_TRUE(CefParseURL(url, parts));
249 
250   CefString spec(&parts.spec);
251   EXPECT_STREQ("custom:something%20else?foo#ref", spec.ToString().c_str());
252   EXPECT_EQ(0U, parts.username.length);
253   EXPECT_EQ(0U, parts.password.length);
254   CefString scheme(&parts.scheme);
255   EXPECT_STREQ("custom", scheme.ToString().c_str());
256   EXPECT_EQ(0U, parts.host.length);
257   EXPECT_EQ(0U, parts.port.length);
258   EXPECT_EQ(0U, parts.origin.length);
259   CefString path(&parts.path);
260   EXPECT_STREQ("something%20else", path.ToString().c_str());
261   CefString query(&parts.query);
262   EXPECT_STREQ("foo", query.ToString().c_str());
263   CefString ref(&parts.fragment);
264   EXPECT_STREQ("ref", ref.ToString().c_str());
265 }
266 
TEST(ParserTest,FormatUrlForSecurityDisplay)267 TEST(ParserTest, FormatUrlForSecurityDisplay) {
268   CefString result;
269 
270   // Omits the protocol if it's standard.
271   result = CefFormatUrlForSecurityDisplay("http://tests.com/foo.html");
272   EXPECT_STREQ("http://tests.com", result.ToString().c_str());
273 
274   // Omits the port if it's the expected value for the protocol.
275   result = CefFormatUrlForSecurityDisplay("http://tests.com:80/foo.html");
276   EXPECT_STREQ("http://tests.com", result.ToString().c_str());
277 
278   // Don't omit non-standard ports.
279   result = CefFormatUrlForSecurityDisplay("http://tests.com:8088/foo.html");
280   EXPECT_STREQ("http://tests.com:8088", result.ToString().c_str());
281 
282   // Don't omit the protocol for file URLs.
283   result = CefFormatUrlForSecurityDisplay("file:///c/tests/foo.html");
284   EXPECT_STREQ("file:///c/tests/foo.html", result.ToString().c_str());
285 }
286 
TEST(ParserTest,GetMimeType)287 TEST(ParserTest, GetMimeType) {
288   CefString mime_type;
289 
290   mime_type = CefGetMimeType("html");
291   EXPECT_STREQ("text/html", mime_type.ToString().c_str());
292 
293   mime_type = CefGetMimeType("txt");
294   EXPECT_STREQ("text/plain", mime_type.ToString().c_str());
295 
296   mime_type = CefGetMimeType("gif");
297   EXPECT_STREQ("image/gif", mime_type.ToString().c_str());
298 }
299 
TEST(ParserTest,Base64Encode)300 TEST(ParserTest, Base64Encode) {
301   const std::string& test_str_decoded = "A test string";
302   const std::string& test_str_encoded = "QSB0ZXN0IHN0cmluZw==";
303   const CefString& encoded_value =
304       CefBase64Encode(test_str_decoded.data(), test_str_decoded.size());
305   EXPECT_STREQ(test_str_encoded.c_str(), encoded_value.ToString().c_str());
306 }
307 
TEST(ParserTest,Base64Decode)308 TEST(ParserTest, Base64Decode) {
309   const std::string& test_str_decoded = "A test string";
310   const std::string& test_str_encoded = "QSB0ZXN0IHN0cmluZw==";
311   CefRefPtr<CefBinaryValue> decoded_value = CefBase64Decode(test_str_encoded);
312   EXPECT_TRUE(decoded_value.get());
313 
314   const size_t decoded_size = decoded_value->GetSize();
315   EXPECT_EQ(test_str_decoded.size(), decoded_size);
316 
317   std::string decoded_str;
318   decoded_str.resize(decoded_size + 1);  // Include space for NUL-terminator.
319   const size_t get_data_result = decoded_value->GetData(
320       const_cast<char*>(decoded_str.data()), decoded_size, 0);
321   EXPECT_EQ(decoded_size, get_data_result);
322   EXPECT_STREQ(test_str_decoded.c_str(), decoded_str.c_str());
323 }
324 
TEST(ParserTest,URIEncode)325 TEST(ParserTest, URIEncode) {
326   const std::string& test_str_decoded = "A test string=";
327   const std::string& test_str_encoded = "A%20test%20string%3D";
328   const CefString& encoded_value = CefURIEncode(test_str_decoded, false);
329   EXPECT_STREQ(test_str_encoded.c_str(), encoded_value.ToString().c_str());
330 }
331 
TEST(ParserTest,URIEncodeWithPlusSpace)332 TEST(ParserTest, URIEncodeWithPlusSpace) {
333   const std::string& test_str_decoded = "A test string=";
334   const std::string& test_str_encoded = "A+test+string%3D";
335   const CefString& encoded_value = CefURIEncode(test_str_decoded, true);
336   EXPECT_STREQ(test_str_encoded.c_str(), encoded_value.ToString().c_str());
337 }
338 
TEST(ParserTest,URIDecode)339 TEST(ParserTest, URIDecode) {
340   const std::string& test_str_decoded = "A test string=";
341   const std::string& test_str_encoded = "A%20test%20string%3D";
342   const CefString& decoded_value = CefURIDecode(
343       test_str_encoded, false,
344       static_cast<cef_uri_unescape_rule_t>(
345           UU_SPACES | UU_URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS));
346   EXPECT_STREQ(test_str_decoded.c_str(), decoded_value.ToString().c_str());
347 }
348 
TEST(ParserTest,URIDecodeWithPlusSpace)349 TEST(ParserTest, URIDecodeWithPlusSpace) {
350   const std::string& test_str_decoded = "A test string=";
351   const std::string& test_str_encoded = "A+test+string%3D";
352   const CefString& decoded_value =
353       CefURIDecode(test_str_encoded, false,
354                    static_cast<cef_uri_unescape_rule_t>(
355                        UU_SPACES | UU_URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS |
356                        UU_REPLACE_PLUS_WITH_SPACE));
357   EXPECT_STREQ(test_str_decoded.c_str(), decoded_value.ToString().c_str());
358 }
359 
TEST(ParserTest,ParseJSONInvalid)360 TEST(ParserTest, ParseJSONInvalid) {
361   const char data[] = "This is my test data";
362   CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
363   EXPECT_FALSE(value.get());
364 }
365 
TEST(ParserTest,ParseJSONNull)366 TEST(ParserTest, ParseJSONNull) {
367   const char data[] = "{\"key1\":null}";
368   CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
369   EXPECT_TRUE(value.get());
370   EXPECT_TRUE(value->IsValid());
371   EXPECT_TRUE(value->GetType() == VTYPE_DICTIONARY);
372   EXPECT_FALSE(value->IsOwned());
373   CefRefPtr<CefDictionaryValue> dict = value->GetDictionary();
374   CefDictionaryValue::KeyList key_list;
375   EXPECT_TRUE(dict->GetKeys(key_list));
376   EXPECT_EQ(1U, key_list.size());
377   EXPECT_EQ("key1", key_list[0].ToString());
378   EXPECT_EQ(VTYPE_NULL, dict->GetType("key1"));
379 
380   // generate string from parsed result
381   CefString result = CefWriteJSON(value, JSON_WRITER_DEFAULT);
382   CefString expected_result = data;
383   EXPECT_EQ(expected_result, result);
384 }
385 
TEST(ParserTest,WriteJSONBinary)386 TEST(ParserTest, WriteJSONBinary) {
387   const char data[] = "\00\01\02";
388   CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
389   CefRefPtr<CefBinaryValue> binary = CefBinaryValue::Create(data, sizeof(data));
390   dict->SetBinary("key1", binary);
391   CefRefPtr<CefValue> node = CefValue::Create();
392   node->SetDictionary(dict);
393   CefString result = CefWriteJSON(node, JSON_WRITER_DEFAULT);
394   CefString expect_result = "";
395   // binary data will be omitted.
396   EXPECT_EQ(expect_result, result);
397 }
398 
TEST(ParserTest,ParseJSONDictionary)399 TEST(ParserTest, ParseJSONDictionary) {
400   const char data[] = "{\"key1\":\"value1\",\"key2\":123,\"key3\":[1,2,3]}";
401   CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
402   EXPECT_TRUE(value.get());
403   EXPECT_TRUE(value->IsValid());
404   EXPECT_FALSE(value->IsOwned());
405   EXPECT_TRUE(value->GetType() == VTYPE_DICTIONARY);
406   CefRefPtr<CefDictionaryValue> dict = value->GetDictionary();
407   CefDictionaryValue::KeyList key_list;
408   EXPECT_TRUE(dict->GetKeys(key_list));
409   EXPECT_EQ(3U, key_list.size());
410   EXPECT_EQ("key1", key_list[0].ToString());
411   EXPECT_EQ("key2", key_list[1].ToString());
412   EXPECT_EQ("key3", key_list[2].ToString());
413   EXPECT_EQ(VTYPE_STRING, dict->GetType("key1"));
414   EXPECT_EQ(dict->GetString("key1"), "value1");
415   EXPECT_EQ(VTYPE_INT, dict->GetType("key2"));
416   EXPECT_EQ(123, dict->GetInt("key2"));
417   EXPECT_EQ(VTYPE_LIST, dict->GetType("key3"));
418   CefRefPtr<CefListValue> key3 = dict->GetList("key3");
419   EXPECT_TRUE(nullptr != key3);
420   EXPECT_TRUE(key3->IsValid());
421   EXPECT_EQ(3U, key3->GetSize());
422   EXPECT_EQ(1, key3->GetInt(0));
423   EXPECT_EQ(2, key3->GetInt(1));
424   EXPECT_EQ(3, key3->GetInt(2));
425 
426   // generate string from parsed result
427   CefString result = CefWriteJSON(value, JSON_WRITER_DEFAULT);
428   CefString expected_result = data;
429   EXPECT_EQ(expected_result, result);
430 }
431 
TEST(ParserTest,ParseJSONList)432 TEST(ParserTest, ParseJSONList) {
433   const char data[] = "[\"value1\", 123, {\"key3\": [1, 2, 3]}]";
434   CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
435   EXPECT_TRUE(value.get());
436   EXPECT_TRUE(value->IsValid());
437   EXPECT_TRUE(value->GetType() == VTYPE_LIST);
438   EXPECT_FALSE(value->IsOwned());
439   CefRefPtr<CefListValue> list = value->GetList();
440   EXPECT_TRUE(nullptr != list);
441   EXPECT_TRUE(list->IsValid());
442   EXPECT_EQ(3U, list->GetSize());
443 
444   EXPECT_EQ(VTYPE_STRING, list->GetType(0));
445   EXPECT_EQ(list->GetString(0), "value1");
446   EXPECT_EQ(VTYPE_INT, list->GetType(1));
447   EXPECT_EQ(123, list->GetInt(1));
448   EXPECT_EQ(VTYPE_DICTIONARY, list->GetType(2));
449   CefRefPtr<CefDictionaryValue> dict = list->GetDictionary(2);
450   CefDictionaryValue::KeyList key_list2;
451   EXPECT_TRUE(dict->GetKeys(key_list2));
452   EXPECT_EQ(1U, key_list2.size());
453   CefRefPtr<CefListValue> list2 = dict->GetList("key3");
454   EXPECT_EQ(3U, list2->GetSize());
455   EXPECT_EQ(1, list2->GetInt(0));
456   EXPECT_EQ(2, list2->GetInt(1));
457   EXPECT_EQ(3, list2->GetInt(2));
458 
459   // generate string from parsed result
460   CefString result = CefWriteJSON(value, JSON_WRITER_DEFAULT);
461   CefString expected_result = "[\"value1\",123,{\"key3\":[1,2,3]}]";
462   EXPECT_EQ(expected_result.ToString(), result.ToString());
463 }
464 
TEST(ParserTest,ParseJSONAndReturnErrorInvalid)465 TEST(ParserTest, ParseJSONAndReturnErrorInvalid) {
466   const char data[] = "This is my test data";
467   CefString error_msg;
468   CefRefPtr<CefValue> value =
469       CefParseJSONAndReturnError(data, JSON_PARSER_RFC, error_msg);
470   CefString expect_error_msg = "Line: 1, column: 1, Unexpected token.";
471   EXPECT_FALSE(value.get());
472   EXPECT_EQ(expect_error_msg, error_msg);
473 }
474 
TEST(ParserTest,ParseJSONAndReturnErrorTrailingComma)475 TEST(ParserTest, ParseJSONAndReturnErrorTrailingComma) {
476   const char data[] = "{\"key1\":123,}";
477   CefString error_msg;
478   CefRefPtr<CefValue> value =
479       CefParseJSONAndReturnError(data, JSON_PARSER_RFC, error_msg);
480   CefString expect_error_msg =
481       "Line: 1, column: 13, Trailing comma not allowed.";
482   EXPECT_FALSE(value.get());
483   EXPECT_EQ(expect_error_msg, error_msg);
484 }
485