1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/json/json_writer.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
8*635a8641SAndroid Build Coastguard Worker #include "base/values.h"
9*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
10*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
11*635a8641SAndroid Build Coastguard Worker
12*635a8641SAndroid Build Coastguard Worker namespace base {
13*635a8641SAndroid Build Coastguard Worker
TEST(JSONWriterTest,BasicTypes)14*635a8641SAndroid Build Coastguard Worker TEST(JSONWriterTest, BasicTypes) {
15*635a8641SAndroid Build Coastguard Worker std::string output_js;
16*635a8641SAndroid Build Coastguard Worker
17*635a8641SAndroid Build Coastguard Worker // Test null.
18*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(Value(), &output_js));
19*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("null", output_js);
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker // Test empty dict.
22*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(DictionaryValue(), &output_js));
23*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("{}", output_js);
24*635a8641SAndroid Build Coastguard Worker
25*635a8641SAndroid Build Coastguard Worker // Test empty list.
26*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(ListValue(), &output_js));
27*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("[]", output_js);
28*635a8641SAndroid Build Coastguard Worker
29*635a8641SAndroid Build Coastguard Worker // Test integer values.
30*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(Value(42), &output_js));
31*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("42", output_js);
32*635a8641SAndroid Build Coastguard Worker
33*635a8641SAndroid Build Coastguard Worker // Test boolean values.
34*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(Value(true), &output_js));
35*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("true", output_js);
36*635a8641SAndroid Build Coastguard Worker
37*635a8641SAndroid Build Coastguard Worker // Test Real values should always have a decimal or an 'e'.
38*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(Value(1.0), &output_js));
39*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("1.0", output_js);
40*635a8641SAndroid Build Coastguard Worker
41*635a8641SAndroid Build Coastguard Worker // Test Real values in the the range (-1, 1) must have leading zeros
42*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(Value(0.2), &output_js));
43*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("0.2", output_js);
44*635a8641SAndroid Build Coastguard Worker
45*635a8641SAndroid Build Coastguard Worker // Test Real values in the the range (-1, 1) must have leading zeros
46*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(Value(-0.8), &output_js));
47*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("-0.8", output_js);
48*635a8641SAndroid Build Coastguard Worker
49*635a8641SAndroid Build Coastguard Worker // Test String values.
50*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(Value("foo"), &output_js));
51*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("\"foo\"", output_js);
52*635a8641SAndroid Build Coastguard Worker }
53*635a8641SAndroid Build Coastguard Worker
TEST(JSONWriterTest,NestedTypes)54*635a8641SAndroid Build Coastguard Worker TEST(JSONWriterTest, NestedTypes) {
55*635a8641SAndroid Build Coastguard Worker std::string output_js;
56*635a8641SAndroid Build Coastguard Worker
57*635a8641SAndroid Build Coastguard Worker // Writer unittests like empty list/dict nesting,
58*635a8641SAndroid Build Coastguard Worker // list list nesting, etc.
59*635a8641SAndroid Build Coastguard Worker DictionaryValue root_dict;
60*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ListValue> list(new ListValue());
61*635a8641SAndroid Build Coastguard Worker std::unique_ptr<DictionaryValue> inner_dict(new DictionaryValue());
62*635a8641SAndroid Build Coastguard Worker inner_dict->SetInteger("inner int", 10);
63*635a8641SAndroid Build Coastguard Worker list->Append(std::move(inner_dict));
64*635a8641SAndroid Build Coastguard Worker list->Append(std::make_unique<ListValue>());
65*635a8641SAndroid Build Coastguard Worker list->AppendBoolean(true);
66*635a8641SAndroid Build Coastguard Worker root_dict.Set("list", std::move(list));
67*635a8641SAndroid Build Coastguard Worker
68*635a8641SAndroid Build Coastguard Worker // Test the pretty-printer.
69*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(root_dict, &output_js));
70*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("{\"list\":[{\"inner int\":10},[],true]}", output_js);
71*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::WriteWithOptions(
72*635a8641SAndroid Build Coastguard Worker root_dict, JSONWriter::OPTIONS_PRETTY_PRINT, &output_js));
73*635a8641SAndroid Build Coastguard Worker
74*635a8641SAndroid Build Coastguard Worker // The pretty-printer uses a different newline style on Windows than on
75*635a8641SAndroid Build Coastguard Worker // other platforms.
76*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
77*635a8641SAndroid Build Coastguard Worker #define JSON_NEWLINE "\r\n"
78*635a8641SAndroid Build Coastguard Worker #else
79*635a8641SAndroid Build Coastguard Worker #define JSON_NEWLINE "\n"
80*635a8641SAndroid Build Coastguard Worker #endif
81*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("{" JSON_NEWLINE
82*635a8641SAndroid Build Coastguard Worker " \"list\": [ {" JSON_NEWLINE
83*635a8641SAndroid Build Coastguard Worker " \"inner int\": 10" JSON_NEWLINE
84*635a8641SAndroid Build Coastguard Worker " }, [ ], true ]" JSON_NEWLINE
85*635a8641SAndroid Build Coastguard Worker "}" JSON_NEWLINE,
86*635a8641SAndroid Build Coastguard Worker output_js);
87*635a8641SAndroid Build Coastguard Worker #undef JSON_NEWLINE
88*635a8641SAndroid Build Coastguard Worker }
89*635a8641SAndroid Build Coastguard Worker
TEST(JSONWriterTest,KeysWithPeriods)90*635a8641SAndroid Build Coastguard Worker TEST(JSONWriterTest, KeysWithPeriods) {
91*635a8641SAndroid Build Coastguard Worker std::string output_js;
92*635a8641SAndroid Build Coastguard Worker
93*635a8641SAndroid Build Coastguard Worker DictionaryValue period_dict;
94*635a8641SAndroid Build Coastguard Worker period_dict.SetKey("a.b", base::Value(3));
95*635a8641SAndroid Build Coastguard Worker period_dict.SetKey("c", base::Value(2));
96*635a8641SAndroid Build Coastguard Worker std::unique_ptr<DictionaryValue> period_dict2(new DictionaryValue());
97*635a8641SAndroid Build Coastguard Worker period_dict2->SetKey("g.h.i.j", base::Value(1));
98*635a8641SAndroid Build Coastguard Worker period_dict.SetWithoutPathExpansion("d.e.f", std::move(period_dict2));
99*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(period_dict, &output_js));
100*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("{\"a.b\":3,\"c\":2,\"d.e.f\":{\"g.h.i.j\":1}}", output_js);
101*635a8641SAndroid Build Coastguard Worker
102*635a8641SAndroid Build Coastguard Worker DictionaryValue period_dict3;
103*635a8641SAndroid Build Coastguard Worker period_dict3.SetInteger("a.b", 2);
104*635a8641SAndroid Build Coastguard Worker period_dict3.SetKey("a.b", base::Value(1));
105*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::Write(period_dict3, &output_js));
106*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("{\"a\":{\"b\":2},\"a.b\":1}", output_js);
107*635a8641SAndroid Build Coastguard Worker }
108*635a8641SAndroid Build Coastguard Worker
TEST(JSONWriterTest,BinaryValues)109*635a8641SAndroid Build Coastguard Worker TEST(JSONWriterTest, BinaryValues) {
110*635a8641SAndroid Build Coastguard Worker std::string output_js;
111*635a8641SAndroid Build Coastguard Worker
112*635a8641SAndroid Build Coastguard Worker // Binary values should return errors unless suppressed via the
113*635a8641SAndroid Build Coastguard Worker // OPTIONS_OMIT_BINARY_VALUES flag.
114*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> root(Value::CreateWithCopiedBuffer("asdf", 4));
115*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(JSONWriter::Write(*root, &output_js));
116*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::WriteWithOptions(
117*635a8641SAndroid Build Coastguard Worker *root, JSONWriter::OPTIONS_OMIT_BINARY_VALUES, &output_js));
118*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(output_js.empty());
119*635a8641SAndroid Build Coastguard Worker
120*635a8641SAndroid Build Coastguard Worker ListValue binary_list;
121*635a8641SAndroid Build Coastguard Worker binary_list.Append(Value::CreateWithCopiedBuffer("asdf", 4));
122*635a8641SAndroid Build Coastguard Worker binary_list.Append(std::make_unique<Value>(5));
123*635a8641SAndroid Build Coastguard Worker binary_list.Append(Value::CreateWithCopiedBuffer("asdf", 4));
124*635a8641SAndroid Build Coastguard Worker binary_list.Append(std::make_unique<Value>(2));
125*635a8641SAndroid Build Coastguard Worker binary_list.Append(Value::CreateWithCopiedBuffer("asdf", 4));
126*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(JSONWriter::Write(binary_list, &output_js));
127*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::WriteWithOptions(
128*635a8641SAndroid Build Coastguard Worker binary_list, JSONWriter::OPTIONS_OMIT_BINARY_VALUES, &output_js));
129*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("[5,2]", output_js);
130*635a8641SAndroid Build Coastguard Worker
131*635a8641SAndroid Build Coastguard Worker DictionaryValue binary_dict;
132*635a8641SAndroid Build Coastguard Worker binary_dict.Set("a", Value::CreateWithCopiedBuffer("asdf", 4));
133*635a8641SAndroid Build Coastguard Worker binary_dict.SetInteger("b", 5);
134*635a8641SAndroid Build Coastguard Worker binary_dict.Set("c", Value::CreateWithCopiedBuffer("asdf", 4));
135*635a8641SAndroid Build Coastguard Worker binary_dict.SetInteger("d", 2);
136*635a8641SAndroid Build Coastguard Worker binary_dict.Set("e", Value::CreateWithCopiedBuffer("asdf", 4));
137*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(JSONWriter::Write(binary_dict, &output_js));
138*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::WriteWithOptions(
139*635a8641SAndroid Build Coastguard Worker binary_dict, JSONWriter::OPTIONS_OMIT_BINARY_VALUES, &output_js));
140*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("{\"b\":5,\"d\":2}", output_js);
141*635a8641SAndroid Build Coastguard Worker }
142*635a8641SAndroid Build Coastguard Worker
TEST(JSONWriterTest,DoublesAsInts)143*635a8641SAndroid Build Coastguard Worker TEST(JSONWriterTest, DoublesAsInts) {
144*635a8641SAndroid Build Coastguard Worker std::string output_js;
145*635a8641SAndroid Build Coastguard Worker
146*635a8641SAndroid Build Coastguard Worker // Test allowing a double with no fractional part to be written as an integer.
147*635a8641SAndroid Build Coastguard Worker Value double_value(1e10);
148*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(JSONWriter::WriteWithOptions(
149*635a8641SAndroid Build Coastguard Worker double_value, JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION,
150*635a8641SAndroid Build Coastguard Worker &output_js));
151*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("10000000000", output_js);
152*635a8641SAndroid Build Coastguard Worker }
153*635a8641SAndroid Build Coastguard Worker
154*635a8641SAndroid Build Coastguard Worker } // namespace base
155