1// Copyright (c) 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/trace_event/trace_event_argument.h"
6
7#include <stddef.h>
8
9#include <utility>
10
11#include "base/values.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14namespace base {
15namespace trace_event {
16
17TEST(TraceEventArgumentTest, FlatDictionary) {
18  scoped_refptr<TracedValue> value = new TracedValue();
19  value->SetInteger("int", 2014);
20  value->SetDouble("double", 0.0);
21  value->SetBoolean("bool", true);
22  value->SetString("string", "string");
23  std::string json = "PREFIX";
24  value->AppendAsTraceFormat(&json);
25  EXPECT_EQ(
26      "PREFIX{\"bool\":true,\"double\":0.0,\"int\":2014,\"string\":\"string\"}",
27      json);
28}
29
30TEST(TraceEventArgumentTest, NoDotPathExpansion) {
31  scoped_refptr<TracedValue> value = new TracedValue();
32  value->SetInteger("in.t", 2014);
33  value->SetDouble("doub.le", 0.0);
34  value->SetBoolean("bo.ol", true);
35  value->SetString("str.ing", "str.ing");
36  std::string json;
37  value->AppendAsTraceFormat(&json);
38  EXPECT_EQ(
39      "{\"bo.ol\":true,\"doub.le\":0.0,\"in.t\":2014,\"str.ing\":\"str.ing\"}",
40      json);
41}
42
43TEST(TraceEventArgumentTest, Hierarchy) {
44  scoped_refptr<TracedValue> value = new TracedValue();
45  value->SetInteger("i0", 2014);
46  value->BeginDictionary("dict1");
47  value->SetInteger("i1", 2014);
48  value->BeginDictionary("dict2");
49  value->SetBoolean("b2", false);
50  value->EndDictionary();
51  value->SetString("s1", "foo");
52  value->EndDictionary();
53  value->SetDouble("d0", 0.0);
54  value->SetBoolean("b0", true);
55  value->BeginArray("a1");
56  value->AppendInteger(1);
57  value->AppendBoolean(true);
58  value->BeginDictionary();
59  value->SetInteger("i2", 3);
60  value->EndDictionary();
61  value->EndArray();
62  value->SetString("s0", "foo");
63  std::string json;
64  value->AppendAsTraceFormat(&json);
65  EXPECT_EQ(
66      "{\"a1\":[1,true,{\"i2\":3}],\"b0\":true,\"d0\":0.0,\"dict1\":{\"dict2\":"
67      "{\"b2\":false},\"i1\":2014,\"s1\":\"foo\"},\"i0\":2014,\"s0\":"
68      "\"foo\"}",
69      json);
70}
71
72TEST(TraceEventArgumentTest, LongStrings) {
73  std::string kLongString = "supercalifragilisticexpialidocious";
74  std::string kLongString2 = "0123456789012345678901234567890123456789";
75  char kLongString3[4096];
76  for (size_t i = 0; i < sizeof(kLongString3); ++i)
77    kLongString3[i] = 'a' + (i % 25);
78  kLongString3[sizeof(kLongString3) - 1] = '\0';
79
80  scoped_refptr<TracedValue> value = new TracedValue();
81  value->SetString("a", "short");
82  value->SetString("b", kLongString);
83  value->BeginArray("c");
84  value->AppendString(kLongString2);
85  value->AppendString("");
86  value->BeginDictionary();
87  value->SetString("a", kLongString3);
88  value->EndDictionary();
89  value->EndArray();
90
91  std::string json;
92  value->AppendAsTraceFormat(&json);
93  EXPECT_EQ("{\"a\":\"short\",\"b\":\"" + kLongString + "\",\"c\":[\"" +
94                kLongString2 + "\",\"\",{\"a\":\"" + kLongString3 + "\"}]}",
95            json);
96}
97
98TEST(TraceEventArgumentTest, PassBaseValue) {
99  FundamentalValue int_value(42);
100  FundamentalValue bool_value(true);
101  FundamentalValue double_value(42.0f);
102
103  auto dict_value = make_scoped_ptr(new DictionaryValue);
104  dict_value->SetBoolean("bool", true);
105  dict_value->SetInteger("int", 42);
106  dict_value->SetDouble("double", 42.0f);
107  dict_value->SetString("string", std::string("a") + "b");
108  dict_value->SetString("string", std::string("a") + "b");
109
110  auto list_value = make_scoped_ptr(new ListValue);
111  list_value->AppendBoolean(false);
112  list_value->AppendInteger(1);
113  list_value->AppendString("in_list");
114  list_value->Append(std::move(dict_value));
115
116  scoped_refptr<TracedValue> value = new TracedValue();
117  value->BeginDictionary("outer_dict");
118  value->SetValue("inner_list", std::move(list_value));
119  value->EndDictionary();
120
121  dict_value.reset();
122  list_value.reset();
123
124  std::string json;
125  value->AppendAsTraceFormat(&json);
126  EXPECT_EQ(
127      "{\"outer_dict\":{\"inner_list\":[false,1,\"in_list\",{\"bool\":true,"
128      "\"double\":42.0,\"int\":42,\"string\":\"ab\"}]}}",
129      json);
130}
131
132TEST(TraceEventArgumentTest, PassTracedValue) {
133  auto dict_value = make_scoped_refptr(new TracedValue);
134  dict_value->SetInteger("a", 1);
135
136  auto nested_dict_value = make_scoped_refptr(new TracedValue);
137  nested_dict_value->SetInteger("b", 2);
138  nested_dict_value->BeginArray("c");
139  nested_dict_value->AppendString("foo");
140  nested_dict_value->EndArray();
141
142  dict_value->SetValue("e", *nested_dict_value);
143
144  // Check the merged result.
145  std::string json;
146  dict_value->AppendAsTraceFormat(&json);
147  EXPECT_EQ("{\"a\":1,\"e\":{\"b\":2,\"c\":[\"foo\"]}}", json);
148
149  // Check that the passed nestd dict was left unouthced.
150  json = "";
151  nested_dict_value->AppendAsTraceFormat(&json);
152  EXPECT_EQ("{\"b\":2,\"c\":[\"foo\"]}", json);
153
154  // And that it is still usable.
155  nested_dict_value->SetInteger("f", 3);
156  nested_dict_value->BeginDictionary("g");
157  nested_dict_value->EndDictionary();
158  json = "";
159  nested_dict_value->AppendAsTraceFormat(&json);
160  EXPECT_EQ("{\"b\":2,\"c\":[\"foo\"],\"f\":3,\"g\":{}}", json);
161}
162
163}  // namespace trace_event
164}  // namespace base
165