1// Copyright 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/memory/scoped_ptr.h"
6#include "base/values.h"
7#include "extensions/renderer/activity_log_converter_strategy.h"
8#include "extensions/renderer/scoped_persistent.h"
9#include "testing/gtest/include/gtest/gtest.h"
10#include "v8/include/v8.h"
11
12using content::V8ValueConverter;
13
14namespace extensions {
15
16class ActivityLogConverterStrategyTest : public testing::Test {
17 public:
18  ActivityLogConverterStrategyTest()
19      : isolate_(v8::Isolate::GetCurrent())
20      , handle_scope_(isolate_)
21      , context_(v8::Context::New(isolate_))
22      , context_scope_(context()) {
23  }
24
25 protected:
26  virtual void SetUp() {
27    converter_.reset(V8ValueConverter::create());
28    strategy_.reset(new ActivityLogConverterStrategy());
29    converter_->SetFunctionAllowed(true);
30    converter_->SetStrategy(strategy_.get());
31  }
32
33  testing::AssertionResult VerifyNull(v8::Local<v8::Value> v8_value) {
34    scoped_ptr<base::Value> value(
35        converter_->FromV8Value(v8_value, context()));
36    if (value->IsType(base::Value::TYPE_NULL))
37      return testing::AssertionSuccess();
38    return testing::AssertionFailure();
39  }
40
41  testing::AssertionResult VerifyBoolean(v8::Local<v8::Value> v8_value,
42                                         bool expected) {
43    bool out;
44    scoped_ptr<base::Value> value(
45        converter_->FromV8Value(v8_value, context()));
46    if (value->IsType(base::Value::TYPE_BOOLEAN)
47        && value->GetAsBoolean(&out)
48        && out == expected)
49      return testing::AssertionSuccess();
50    return testing::AssertionFailure();
51  }
52
53  testing::AssertionResult VerifyInteger(v8::Local<v8::Value> v8_value,
54                                         int expected) {
55    int out;
56    scoped_ptr<base::Value> value(
57        converter_->FromV8Value(v8_value, context()));
58    if (value->IsType(base::Value::TYPE_INTEGER)
59        && value->GetAsInteger(&out)
60        && out == expected)
61      return testing::AssertionSuccess();
62    return testing::AssertionFailure();
63  }
64
65  testing::AssertionResult VerifyDouble(v8::Local<v8::Value> v8_value,
66                                        double expected) {
67    double out;
68    scoped_ptr<base::Value> value(
69        converter_->FromV8Value(v8_value, context()));
70    if (value->IsType(base::Value::TYPE_DOUBLE)
71        && value->GetAsDouble(&out)
72        && out == expected)
73      return testing::AssertionSuccess();
74    return testing::AssertionFailure();
75  }
76
77  testing::AssertionResult VerifyString(v8::Local<v8::Value> v8_value,
78                                        const std::string& expected) {
79    std::string out;
80    scoped_ptr<base::Value> value(
81        converter_->FromV8Value(v8_value, context()));
82    if (value->IsType(base::Value::TYPE_STRING)
83        && value->GetAsString(&out)
84        && out == expected)
85      return testing::AssertionSuccess();
86    return testing::AssertionFailure();
87  }
88
89  v8::Handle<v8::Context> context() const {
90    return context_.NewHandle(isolate_);
91  }
92
93  v8::Isolate* isolate_;
94  v8::HandleScope handle_scope_;
95  ScopedPersistent<v8::Context> context_;
96  v8::Context::Scope context_scope_;
97  scoped_ptr<V8ValueConverter> converter_;
98  scoped_ptr<ActivityLogConverterStrategy> strategy_;
99};
100
101TEST_F(ActivityLogConverterStrategyTest, ConversionTest) {
102  const char* source = "(function() {"
103      "function foo() {}"
104      "return {"
105        "null: null,"
106        "true: true,"
107        "false: false,"
108        "positive_int: 42,"
109        "negative_int: -42,"
110        "zero: 0,"
111        "double: 88.8,"
112        "big_integral_double: 9007199254740992.0,"  // 2.0^53
113        "string: \"foobar\","
114        "empty_string: \"\","
115        "dictionary: {"
116          "foo: \"bar\","
117          "hot: \"dog\","
118        "},"
119        "empty_dictionary: {},"
120        "list: [ \"monkey\", \"balls\" ],"
121        "empty_list: [],"
122        "function: function() {},"
123        "named_function: foo"
124      "};"
125      "})();";
126
127  v8::Handle<v8::Script> script(
128      v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source)));
129  v8::Handle<v8::Object> v8_object = script->Run().As<v8::Object>();
130
131  EXPECT_TRUE(VerifyString(v8_object, "[Object]"));
132  EXPECT_TRUE(
133      VerifyNull(v8_object->Get(v8::String::NewFromUtf8(isolate_, "null"))));
134  EXPECT_TRUE(VerifyBoolean(
135      v8_object->Get(v8::String::NewFromUtf8(isolate_, "true")), true));
136  EXPECT_TRUE(VerifyBoolean(
137      v8_object->Get(v8::String::NewFromUtf8(isolate_, "false")), false));
138  EXPECT_TRUE(VerifyInteger(
139      v8_object->Get(v8::String::NewFromUtf8(isolate_, "positive_int")), 42));
140  EXPECT_TRUE(VerifyInteger(
141      v8_object->Get(v8::String::NewFromUtf8(isolate_, "negative_int")), -42));
142  EXPECT_TRUE(VerifyInteger(
143      v8_object->Get(v8::String::NewFromUtf8(isolate_, "zero")), 0));
144  EXPECT_TRUE(VerifyDouble(
145      v8_object->Get(v8::String::NewFromUtf8(isolate_, "double")), 88.8));
146  EXPECT_TRUE(VerifyDouble(
147      v8_object->Get(v8::String::NewFromUtf8(isolate_, "big_integral_double")),
148      9007199254740992.0));
149  EXPECT_TRUE(VerifyString(
150      v8_object->Get(v8::String::NewFromUtf8(isolate_, "string")), "foobar"));
151  EXPECT_TRUE(VerifyString(
152      v8_object->Get(v8::String::NewFromUtf8(isolate_, "empty_string")), ""));
153  EXPECT_TRUE(VerifyString(
154      v8_object->Get(v8::String::NewFromUtf8(isolate_, "dictionary")),
155      "[Object]"));
156  EXPECT_TRUE(VerifyString(
157      v8_object->Get(v8::String::NewFromUtf8(isolate_, "empty_dictionary")),
158      "[Object]"));
159  EXPECT_TRUE(VerifyString(
160      v8_object->Get(v8::String::NewFromUtf8(isolate_, "list")), "[Array]"));
161  EXPECT_TRUE(VerifyString(
162      v8_object->Get(v8::String::NewFromUtf8(isolate_, "empty_list")),
163      "[Array]"));
164  EXPECT_TRUE(VerifyString(
165      v8_object->Get(v8::String::NewFromUtf8(isolate_, "function")),
166      "[Function]"));
167  EXPECT_TRUE(VerifyString(
168      v8_object->Get(v8::String::NewFromUtf8(isolate_, "named_function")),
169      "[Function foo()]"));
170}
171
172}  // namespace extensions
173