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