|  | // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "base/trace_event/trace_event_argument.h" | 
|  |  | 
|  | #include <stddef.h> | 
|  |  | 
|  | #include <utility> | 
|  |  | 
|  | #include "base/memory/ptr_util.h" | 
|  | #include "base/values.h" | 
|  | #include "testing/gtest/include/gtest/gtest.h" | 
|  |  | 
|  | namespace base { | 
|  | namespace trace_event { | 
|  |  | 
|  | TEST(TraceEventArgumentTest, FlatDictionary) { | 
|  | std::unique_ptr<TracedValue> value(new TracedValue()); | 
|  | value->SetBoolean("bool", true); | 
|  | value->SetDouble("double", 0.0); | 
|  | value->SetInteger("int", 2014); | 
|  | value->SetString("string", "string"); | 
|  | std::string json = "PREFIX"; | 
|  | value->AppendAsTraceFormat(&json); | 
|  | EXPECT_EQ( | 
|  | "PREFIX{\"bool\":true,\"double\":0.0,\"int\":2014,\"string\":\"string\"}", | 
|  | json); | 
|  | } | 
|  |  | 
|  | TEST(TraceEventArgumentTest, NoDotPathExpansion) { | 
|  | std::unique_ptr<TracedValue> value(new TracedValue()); | 
|  | value->SetBoolean("bo.ol", true); | 
|  | value->SetDouble("doub.le", 0.0); | 
|  | value->SetInteger("in.t", 2014); | 
|  | value->SetString("str.ing", "str.ing"); | 
|  | std::string json; | 
|  | value->AppendAsTraceFormat(&json); | 
|  | EXPECT_EQ( | 
|  | "{\"bo.ol\":true,\"doub.le\":0.0,\"in.t\":2014,\"str.ing\":\"str.ing\"}", | 
|  | json); | 
|  | } | 
|  |  | 
|  | TEST(TraceEventArgumentTest, Hierarchy) { | 
|  | std::unique_ptr<TracedValue> value(new TracedValue()); | 
|  | value->BeginArray("a1"); | 
|  | value->AppendInteger(1); | 
|  | value->AppendBoolean(true); | 
|  | value->BeginDictionary(); | 
|  | value->SetInteger("i2", 3); | 
|  | value->EndDictionary(); | 
|  | value->EndArray(); | 
|  | value->SetBoolean("b0", true); | 
|  | value->SetDouble("d0", 0.0); | 
|  | value->BeginDictionary("dict1"); | 
|  | value->BeginDictionary("dict2"); | 
|  | value->SetBoolean("b2", false); | 
|  | value->EndDictionary(); | 
|  | value->SetInteger("i1", 2014); | 
|  | value->SetString("s1", "foo"); | 
|  | value->EndDictionary(); | 
|  | value->SetInteger("i0", 2014); | 
|  | value->SetString("s0", "foo"); | 
|  | std::string json; | 
|  | value->AppendAsTraceFormat(&json); | 
|  | EXPECT_EQ( | 
|  | "{\"a1\":[1,true,{\"i2\":3}],\"b0\":true,\"d0\":0.0,\"dict1\":{\"dict2\":" | 
|  | "{\"b2\":false},\"i1\":2014,\"s1\":\"foo\"},\"i0\":2014,\"s0\":" | 
|  | "\"foo\"}", | 
|  | json); | 
|  | } | 
|  |  | 
|  | TEST(TraceEventArgumentTest, LongStrings) { | 
|  | std::string kLongString = "supercalifragilisticexpialidocious"; | 
|  | std::string kLongString2 = "0123456789012345678901234567890123456789"; | 
|  | char kLongString3[4096]; | 
|  | for (size_t i = 0; i < sizeof(kLongString3); ++i) | 
|  | kLongString3[i] = 'a' + (i % 25); | 
|  | kLongString3[sizeof(kLongString3) - 1] = '\0'; | 
|  |  | 
|  | std::unique_ptr<TracedValue> value(new TracedValue()); | 
|  | value->SetString("a", "short"); | 
|  | value->SetString("b", kLongString); | 
|  | value->BeginArray("c"); | 
|  | value->AppendString(kLongString2); | 
|  | value->AppendString(""); | 
|  | value->BeginDictionary(); | 
|  | value->SetString("a", kLongString3); | 
|  | value->EndDictionary(); | 
|  | value->EndArray(); | 
|  |  | 
|  | std::string json; | 
|  | value->AppendAsTraceFormat(&json); | 
|  | EXPECT_EQ("{\"a\":\"short\",\"b\":\"" + kLongString + "\",\"c\":[\"" + | 
|  | kLongString2 + "\",\"\",{\"a\":\"" + kLongString3 + "\"}]}", | 
|  | json); | 
|  | } | 
|  |  | 
|  | TEST(TraceEventArgumentTest, PassBaseValue) { | 
|  | Value int_value(42); | 
|  | Value bool_value(true); | 
|  | Value double_value(42.0f); | 
|  |  | 
|  | auto dict_value = WrapUnique(new DictionaryValue); | 
|  | dict_value->SetBoolean("bool", true); | 
|  | dict_value->SetInteger("int", 42); | 
|  | dict_value->SetDouble("double", 42.0f); | 
|  | dict_value->SetString("string", std::string("a") + "b"); | 
|  | dict_value->SetString("string", std::string("a") + "b"); | 
|  |  | 
|  | auto list_value = WrapUnique(new ListValue); | 
|  | list_value->AppendBoolean(false); | 
|  | list_value->AppendInteger(1); | 
|  | list_value->AppendString("in_list"); | 
|  | list_value->Append(std::move(dict_value)); | 
|  |  | 
|  | std::unique_ptr<TracedValue> value(new TracedValue()); | 
|  | value->BeginDictionary("outer_dict"); | 
|  | value->SetValue("inner_list", std::move(list_value)); | 
|  | value->EndDictionary(); | 
|  |  | 
|  | dict_value.reset(); | 
|  | list_value.reset(); | 
|  |  | 
|  | std::string json; | 
|  | value->AppendAsTraceFormat(&json); | 
|  | EXPECT_EQ( | 
|  | "{\"outer_dict\":{\"inner_list\":[false,1,\"in_list\",{\"bool\":true," | 
|  | "\"double\":42.0,\"int\":42,\"string\":\"ab\"}]}}", | 
|  | json); | 
|  | } | 
|  |  | 
|  | TEST(TraceEventArgumentTest, PassTracedValue) { | 
|  | auto dict_value = std::make_unique<TracedValue>(); | 
|  | dict_value->SetInteger("a", 1); | 
|  |  | 
|  | auto nested_dict_value = std::make_unique<TracedValue>(); | 
|  | nested_dict_value->SetInteger("b", 2); | 
|  | nested_dict_value->BeginArray("c"); | 
|  | nested_dict_value->AppendString("foo"); | 
|  | nested_dict_value->EndArray(); | 
|  |  | 
|  | dict_value->SetValue("e", *nested_dict_value); | 
|  |  | 
|  | // Check the merged result. | 
|  | std::string json; | 
|  | dict_value->AppendAsTraceFormat(&json); | 
|  | EXPECT_EQ("{\"a\":1,\"e\":{\"b\":2,\"c\":[\"foo\"]}}", json); | 
|  |  | 
|  | // Check that the passed nestd dict was left unouthced. | 
|  | json = ""; | 
|  | nested_dict_value->AppendAsTraceFormat(&json); | 
|  | EXPECT_EQ("{\"b\":2,\"c\":[\"foo\"]}", json); | 
|  |  | 
|  | // And that it is still usable. | 
|  | nested_dict_value->SetInteger("f", 3); | 
|  | nested_dict_value->BeginDictionary("g"); | 
|  | nested_dict_value->EndDictionary(); | 
|  | json = ""; | 
|  | nested_dict_value->AppendAsTraceFormat(&json); | 
|  | EXPECT_EQ("{\"b\":2,\"c\":[\"foo\"],\"f\":3,\"g\":{}}", json); | 
|  | } | 
|  |  | 
|  | }  // namespace trace_event | 
|  | }  // namespace base |