This patch combine three patch which is related to "--gcov" flag.
[platform/framework/web/chromium-efl.git] / gin / converter_unittest.cc
1 // Copyright 2013 The Chromium Authors
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 "gin/converter.h"
6
7 #include <limits.h>
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <string>
12
13 #include "base/compiler_specific.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "gin/function_template.h"
16 #include "gin/handle.h"
17 #include "gin/public/isolate_holder.h"
18 #include "gin/test/v8_test.h"
19 #include "gin/wrappable.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "v8/include/v8-container.h"
23 #include "v8/include/v8-forward.h"
24 #include "v8/include/v8-function.h"
25 #include "v8/include/v8-isolate.h"
26 #include "v8/include/v8-primitive.h"
27 #include "v8/include/v8-template.h"
28
29 namespace gin {
30
31 using v8::Array;
32 using v8::Boolean;
33 using v8::HandleScope;
34 using v8::Integer;
35 using v8::Local;
36 using v8::Null;
37 using v8::Number;
38 using v8::Object;
39 using v8::String;
40 using v8::Undefined;
41 using v8::Value;
42
43 typedef V8Test ConverterTest;
44
45 TEST_F(ConverterTest, Bool) {
46   HandleScope handle_scope(instance_->isolate());
47
48   EXPECT_TRUE(Converter<bool>::ToV8(instance_->isolate(), true)->StrictEquals(
49       Boolean::New(instance_->isolate(), true)));
50   EXPECT_TRUE(Converter<bool>::ToV8(instance_->isolate(), false)->StrictEquals(
51       Boolean::New(instance_->isolate(), false)));
52
53   struct {
54     Local<Value> input;
55     bool expected;
56   } test_data[] = {
57       {Boolean::New(instance_->isolate(), false).As<Value>(), false},
58       {Boolean::New(instance_->isolate(), true).As<Value>(), true},
59       {Number::New(instance_->isolate(), 0).As<Value>(), false},
60       {Number::New(instance_->isolate(), 1).As<Value>(), true},
61       {Number::New(instance_->isolate(), -1).As<Value>(), true},
62       {Number::New(instance_->isolate(), 0.1).As<Value>(), true},
63       {String::NewFromUtf8(instance_->isolate(), "", v8::NewStringType::kNormal)
64            .ToLocalChecked()
65            .As<Value>(),
66        false},
67       {String::NewFromUtf8(instance_->isolate(), "foo",
68                            v8::NewStringType::kNormal)
69            .ToLocalChecked()
70            .As<Value>(),
71        true},
72       {Object::New(instance_->isolate()).As<Value>(), true},
73       {Null(instance_->isolate()).As<Value>(), false},
74       {Undefined(instance_->isolate()).As<Value>(), false},
75   };
76
77   for (size_t i = 0; i < std::size(test_data); ++i) {
78     bool result = false;
79     EXPECT_TRUE(Converter<bool>::FromV8(instance_->isolate(),
80                                         test_data[i].input, &result));
81     EXPECT_EQ(test_data[i].expected, result);
82
83     result = true;
84     EXPECT_TRUE(Converter<bool>::FromV8(instance_->isolate(),
85                                         test_data[i].input, &result));
86     EXPECT_EQ(test_data[i].expected, result);
87   }
88 }
89
90 TEST_F(ConverterTest, String16) {
91   v8::Isolate* isolate = instance_->isolate();
92
93   HandleScope handle_scope(isolate);
94
95   EXPECT_TRUE(Converter<std::u16string>::ToV8(isolate, u"")
96                   ->StrictEquals(StringToV8(isolate, "")));
97   EXPECT_TRUE(Converter<std::u16string>::ToV8(isolate, u"hello")
98                   ->StrictEquals(StringToV8(isolate, "hello")));
99
100   std::u16string result;
101
102   ASSERT_FALSE(
103       Converter<std::u16string>::FromV8(isolate, v8::False(isolate), &result));
104   ASSERT_FALSE(
105       Converter<std::u16string>::FromV8(isolate, v8::True(isolate), &result));
106   ASSERT_TRUE(Converter<std::u16string>::FromV8(
107       isolate, v8::String::Empty(isolate), &result));
108   EXPECT_EQ(result, std::u16string());
109   ASSERT_TRUE(Converter<std::u16string>::FromV8(
110       isolate, StringToV8(isolate, "hello"), &result));
111   EXPECT_EQ(result, u"hello");
112 }
113
114 TEST_F(ConverterTest, Int32) {
115   HandleScope handle_scope(instance_->isolate());
116
117   int test_data_to[] = {-1, 0, 1};
118   for (size_t i = 0; i < std::size(test_data_to); ++i) {
119     EXPECT_TRUE(Converter<int32_t>::ToV8(instance_->isolate(), test_data_to[i])
120                     ->StrictEquals(
121                           Integer::New(instance_->isolate(), test_data_to[i])));
122   }
123
124   struct {
125     v8::Local<v8::Value> input;
126     bool expect_success;
127     int expected_result;
128   } test_data_from[] = {
129       {Boolean::New(instance_->isolate(), false).As<Value>(), false, 0},
130       {Boolean::New(instance_->isolate(), true).As<Value>(), false, 0},
131       {Integer::New(instance_->isolate(), -1).As<Value>(), true, -1},
132       {Integer::New(instance_->isolate(), 0).As<Value>(), true, 0},
133       {Integer::New(instance_->isolate(), 1).As<Value>(), true, 1},
134       {Number::New(instance_->isolate(), -1).As<Value>(), true, -1},
135       {Number::New(instance_->isolate(), 1.1).As<Value>(), false, 0},
136       {String::NewFromUtf8(instance_->isolate(), "42",
137                            v8::NewStringType::kNormal)
138            .ToLocalChecked()
139            .As<Value>(),
140        false, 0},
141       {String::NewFromUtf8(instance_->isolate(), "foo",
142                            v8::NewStringType::kNormal)
143            .ToLocalChecked()
144            .As<Value>(),
145        false, 0},
146       {Object::New(instance_->isolate()).As<Value>(), false, 0},
147       {Array::New(instance_->isolate()).As<Value>(), false, 0},
148       {v8::Null(instance_->isolate()).As<Value>(), false, 0},
149       {v8::Undefined(instance_->isolate()).As<Value>(), false, 0},
150   };
151
152   for (size_t i = 0; i < std::size(test_data_from); ++i) {
153     int32_t result = std::numeric_limits<int32_t>::min();
154     bool success = Converter<int32_t>::FromV8(instance_->isolate(),
155                                               test_data_from[i].input, &result);
156     EXPECT_EQ(test_data_from[i].expect_success, success) << i;
157     if (success)
158       EXPECT_EQ(test_data_from[i].expected_result, result) << i;
159   }
160 }
161
162 TEST_F(ConverterTest, Vector) {
163   HandleScope handle_scope(instance_->isolate());
164
165   std::vector<int> expected;
166   expected.push_back(-1);
167   expected.push_back(0);
168   expected.push_back(1);
169
170   auto js_array =
171       Converter<std::vector<int>>::ToV8(instance_->isolate(), expected)
172           .As<Array>();
173   EXPECT_EQ(3u, js_array->Length());
174   v8::Local<v8::Context> context = instance_->isolate()->GetCurrentContext();
175   for (size_t i = 0; i < expected.size(); ++i) {
176     EXPECT_TRUE(
177         Integer::New(instance_->isolate(), expected[i])
178             ->StrictEquals(
179                 js_array->Get(context, static_cast<int>(i)).ToLocalChecked()));
180   }
181 }
182
183 TEST_F(ConverterTest, VectorOfVectors) {
184   HandleScope handle_scope(instance_->isolate());
185
186   std::vector<std::vector<int>> vector_of_vectors = {
187       {1, 2, 3}, {4, 5, 6},
188   };
189
190   v8::Local<v8::Value> v8_value =
191       ConvertToV8(instance_->isolate(), vector_of_vectors);
192   std::vector<std::vector<int>> out_value;
193   ASSERT_TRUE(ConvertFromV8(instance_->isolate(), v8_value, &out_value));
194   EXPECT_THAT(out_value, testing::ContainerEq(vector_of_vectors));
195 }
196
197 namespace {
198
199 class MyObject : public Wrappable<MyObject> {
200  public:
201   static WrapperInfo kWrapperInfo;
202
203   static gin::Handle<MyObject> Create(v8::Isolate* isolate) {
204     return CreateHandle(isolate, new MyObject());
205   }
206 };
207
208 WrapperInfo MyObject::kWrapperInfo = {kEmbedderNativeGin};
209
210 }  // namespace
211
212 TEST_F(ConverterTest, VectorOfWrappables) {
213   v8::Isolate* isolate = instance_->isolate();
214   v8::HandleScope handle_scope(isolate);
215
216   Handle<MyObject> obj = MyObject::Create(isolate);
217   std::vector<MyObject*> vector = {obj.get()};
218   v8::MaybeLocal<v8::Value> maybe = ConvertToV8(isolate, vector);
219   v8::Local<v8::Value> array;
220   ASSERT_TRUE(maybe.ToLocal(&array));
221   v8::Local<v8::Value> array2;
222   ASSERT_TRUE(TryConvertToV8(isolate, vector, &array2));
223
224   std::vector<MyObject*> out_value;
225   ASSERT_TRUE(ConvertFromV8(isolate, array, &out_value));
226   EXPECT_THAT(out_value, testing::ContainerEq(vector));
227   std::vector<MyObject*> out_value2;
228   ASSERT_TRUE(ConvertFromV8(isolate, array2, &out_value2));
229   EXPECT_THAT(out_value2, testing::ContainerEq(vector));
230 }
231
232 namespace {
233
234 class MoveOnlyObject {
235  public:
236   MoveOnlyObject() = default;
237   MoveOnlyObject(const MoveOnlyObject&) = delete;
238   MoveOnlyObject& operator=(const MoveOnlyObject&) = delete;
239
240   MoveOnlyObject(MoveOnlyObject&&) noexcept = default;
241   MoveOnlyObject& operator=(MoveOnlyObject&&) noexcept = default;
242 };
243
244 }  // namespace
245
246 template <>
247 struct Converter<MoveOnlyObject> {
248   static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, MoveOnlyObject in) {
249     return v8::Undefined(isolate);
250   }
251   static bool FromV8(v8::Isolate* isolate,
252                      v8::Local<v8::Value> val,
253                      MoveOnlyObject* out) {
254     *out = MoveOnlyObject();
255     return true;
256   }
257 };
258
259 TEST_F(ConverterTest, MoveOnlyParameters) {
260   v8::Isolate* isolate = instance_->isolate();
261   v8::HandleScope handle_scope(isolate);
262
263   auto receives_move_only_obj = [](MoveOnlyObject obj) {};
264   auto func_templ = gin::CreateFunctionTemplate(
265       isolate, base::BindRepeating(receives_move_only_obj));
266
267   v8::Local<v8::Context> context = instance_->isolate()->GetCurrentContext();
268   auto func = func_templ->GetFunction(context).ToLocalChecked();
269   v8::Local<v8::Value> argv[] = {v8::Undefined(isolate)};
270   func->Call(context, v8::Undefined(isolate), 1, argv).ToLocalChecked();
271 }
272
273 }  // namespace gin