- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / chromedriver / chrome / console_logger_unittest.cc
1 // Copyright (c) 2013 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 "chrome/test/chromedriver/chrome/console_logger.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/format_macros.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/time/time.h"
11 #include "base/values.h"
12 #include "chrome/test/chromedriver/chrome/log.h"
13 #include "chrome/test/chromedriver/chrome/status.h"
14 #include "chrome/test/chromedriver/chrome/stub_devtools_client.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace {
18
19 class FakeDevToolsClient : public StubDevToolsClient {
20  public:
21   explicit FakeDevToolsClient(const std::string& id)
22       : id_(id), listener_(NULL) {}
23   virtual ~FakeDevToolsClient() {}
24
25   std::string PopSentCommand() {
26     std::string command;
27     if (!sent_command_queue_.empty()) {
28       command = sent_command_queue_.front();
29       sent_command_queue_.pop_front();
30     }
31     return command;
32   }
33
34   Status TriggerEvent(const std::string& method,
35                     const base::DictionaryValue& params) {
36     return listener_->OnEvent(this, method, params);
37   }
38
39   // Overridden from DevToolsClient:
40   virtual Status ConnectIfNecessary() OVERRIDE {
41     return listener_->OnConnected(this);
42   }
43
44   virtual Status SendCommandAndGetResult(
45       const std::string& method,
46       const base::DictionaryValue& params,
47       scoped_ptr<base::DictionaryValue>* result) OVERRIDE {
48     sent_command_queue_.push_back(method);
49     return Status(kOk);
50   }
51
52   virtual void AddListener(DevToolsEventListener* listener) OVERRIDE {
53     CHECK(!listener_);
54     listener_ = listener;
55   }
56
57   virtual const std::string& GetId() OVERRIDE {
58     return id_;
59   }
60
61  private:
62   const std::string id_;  // WebView id.
63   std::list<std::string> sent_command_queue_;  // Commands that were sent.
64   DevToolsEventListener* listener_;  // The fake allows only one event listener.
65 };
66
67 struct LogEntry {
68   const base::Time timestamp;
69   const Log::Level level;
70   const std::string source;
71   const std::string message;
72
73   LogEntry(const base::Time& timestamp,
74            Log::Level level,
75            const std::string& source,
76            const std::string& message)
77       : timestamp(timestamp), level(level), source(source), message(message) {}
78 };
79
80 class FakeLog : public Log {
81  public:
82   virtual void AddEntryTimestamped(const base::Time& timestamp,
83                                    Level level,
84                                    const std::string& source,
85                                    const std::string& message) OVERRIDE;
86
87   const ScopedVector<LogEntry>& GetEntries() {
88     return entries_;
89   }
90
91 private:
92   ScopedVector<LogEntry> entries_;
93 };
94
95 void FakeLog::AddEntryTimestamped(const base::Time& timestamp,
96                                   Level level,
97                                   const std::string& source,
98                                   const std::string& message) {
99   entries_.push_back(new LogEntry(timestamp, level, source, message));
100 }
101
102 void ValidateLogEntry(const LogEntry *entry,
103                       Log::Level expected_level,
104                       const std::string& expected_source,
105                       const std::string& expected_message) {
106   EXPECT_EQ(expected_level, entry->level);
107   EXPECT_EQ(expected_source, entry->source);
108   EXPECT_LT(0, entry->timestamp.ToTimeT());
109   EXPECT_EQ(expected_message, entry->message);
110 }
111
112 void ConsoleLogParams(base::DictionaryValue* out_params,
113                       const char* source,
114                       const char* url,
115                       const char* level,
116                       int line,
117                       int column,
118                       const char* text) {
119   if (source != NULL)
120     out_params->SetString("message.source", source);
121   if (url != NULL)
122     out_params->SetString("message.url", url);
123   if (level != NULL)
124     out_params->SetString("message.level", level);
125   if (line != -1)
126     out_params->SetInteger("message.line", line);
127   if (column != -1)
128     out_params->SetInteger("message.column", column);
129   if (text != NULL)
130     out_params->SetString("message.text", text);
131 }
132
133 }  // namespace
134
135 TEST(ConsoleLogger, ConsoleMessages) {
136   FakeDevToolsClient client("webview");
137   FakeLog log;
138   ConsoleLogger logger(&log);
139
140   client.AddListener(&logger);
141   logger.OnConnected(&client);
142   EXPECT_EQ("Console.enable", client.PopSentCommand());
143   EXPECT_TRUE(client.PopSentCommand().empty());
144
145   base::DictionaryValue params1;  // All fields are set.
146   ConsoleLogParams(&params1, "source1", "url1", "debug", 10, 1, "text1");
147   ASSERT_EQ(kOk, client.TriggerEvent("Console.messageAdded", params1).code());
148   // Ignored -- wrong method.
149   ASSERT_EQ(kOk, client.TriggerEvent("Console.gaga", params1).code());
150
151   base::DictionaryValue params2;  // All optionals are not set.
152   ConsoleLogParams(&params2, "source2", NULL, "log", -1, -1, "text2");
153   ASSERT_EQ(kOk, client.TriggerEvent("Console.messageAdded", params2).code());
154
155   base::DictionaryValue params3;  // Line without column, no source.
156   ConsoleLogParams(&params3, NULL, "url3", "warning", 30, -1, "text3");
157   ASSERT_EQ(kOk, client.TriggerEvent("Console.messageAdded", params3).code());
158
159   base::DictionaryValue params4;  // Column without line.
160   ConsoleLogParams(&params4, "source4", "url4", "error", -1, 4, "text4");
161   ASSERT_EQ(kOk, client.TriggerEvent("Console.messageAdded", params4).code());
162
163   base::DictionaryValue params5;  // Bad level name.
164   ConsoleLogParams(&params5, "source5", "url5", "gaga", 50, 5, "ulala");
165   ASSERT_EQ(kOk, client.TriggerEvent("Console.messageAdded", params5).code());
166
167   base::DictionaryValue params6;  // Unset level.
168   ConsoleLogParams(&params6, "source6", "url6", NULL, 60, 6, NULL);
169   ASSERT_EQ(kOk, client.TriggerEvent("Console.messageAdded", params6).code());
170
171   base::DictionaryValue params7;  // No text.
172   ConsoleLogParams(&params7, "source7", "url7", "log", -1, -1, NULL);
173   ASSERT_EQ(kOk, client.TriggerEvent("Console.messageAdded", params7).code());
174
175   base::DictionaryValue params8;  // No message object.
176   params8.SetInteger("gaga", 8);
177   ASSERT_EQ(kOk, client.TriggerEvent("Console.messageAdded", params8).code());
178
179   EXPECT_TRUE(client.PopSentCommand().empty());  // No other commands sent.
180
181   ASSERT_EQ(8u, log.GetEntries().size());
182   ValidateLogEntry(log.GetEntries()[0], Log::kDebug, "source1",
183                    "url1 10:1 text1");
184   ValidateLogEntry(log.GetEntries()[1], Log::kInfo, "source2",
185                    "source2 - text2");
186   ValidateLogEntry(log.GetEntries()[2], Log::kWarning, "", "url3 30 text3");
187   ValidateLogEntry(log.GetEntries()[3], Log::kError, "source4",
188                    "url4 - text4");
189   ValidateLogEntry(
190       log.GetEntries()[4], Log::kWarning, "",
191       "{\"message\":{\"column\":5,\"level\":\"gaga\",\"line\":50,"
192       "\"source\":\"source5\",\"text\":\"ulala\",\"url\":\"url5\"}}");
193   ValidateLogEntry(
194       log.GetEntries()[5], Log::kWarning, "",
195       "{\"message\":{\"column\":6,\"line\":60,"
196       "\"source\":\"source6\",\"url\":\"url6\"}}");
197   ValidateLogEntry(
198       log.GetEntries()[6], Log::kWarning, "",
199       "{\"message\":{\"level\":\"log\","
200       "\"source\":\"source7\",\"url\":\"url7\"}}");
201   ValidateLogEntry(log.GetEntries()[7], Log::kWarning, "", "{\"gaga\":8}");
202 }