1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/basictypes.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/float_util.h"
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/stringprintf.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/common/android/gin_java_bridge_value.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/java/gin_java_bridge_value_converter.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "v8/include/v8.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace content {
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class GinJavaBridgeValueConverterTest : public testing::Test {
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GinJavaBridgeValueConverterTest()
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : isolate_(v8::Isolate::GetCurrent()) {
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) protected:
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void SetUp() {
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    v8::HandleScope handle_scope(isolate_);
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_);
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    context_.Reset(isolate_, v8::Context::New(isolate_, NULL, global));
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void TearDown() {
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    context_.Reset();
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Isolate* isolate_;
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Context for the JavaScript in the test.
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Persistent<v8::Context> context_;
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(GinJavaBridgeValueConverterTest, BasicValues) {
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::HandleScope handle_scope(isolate_);
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Local<v8::Context> context =
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      v8::Local<v8::Context>::New(isolate_, context_);
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Context::Scope context_scope(context);
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<GinJavaBridgeValueConverter> converter(
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new GinJavaBridgeValueConverter());
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Handle<v8::Primitive> v8_undefined(v8::Undefined(isolate_));
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<base::Value> undefined(
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      converter->FromV8Value(v8_undefined, context));
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(undefined.get());
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(GinJavaBridgeValue::ContainsGinJavaBridgeValue(undefined.get()));
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<const GinJavaBridgeValue> undefined_value(
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GinJavaBridgeValue::FromValue(undefined.get()));
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(undefined_value.get());
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(undefined_value->IsType(GinJavaBridgeValue::TYPE_UNDEFINED));
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Handle<v8::Number> v8_infinity(
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      v8::Number::New(isolate_, std::numeric_limits<double>::infinity()));
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<base::Value> infinity(
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      converter->FromV8Value(v8_infinity, context));
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(infinity.get());
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GinJavaBridgeValue::ContainsGinJavaBridgeValue(infinity.get()));
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<const GinJavaBridgeValue> infinity_value(
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GinJavaBridgeValue::FromValue(infinity.get()));
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(infinity_value.get());
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  float native_float;
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      infinity_value->IsType(GinJavaBridgeValue::TYPE_NONFINITE));
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(infinity_value->GetAsNonFinite(&native_float));
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(base::IsFinite(native_float));
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(base::IsNaN(native_float));
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(GinJavaBridgeValueConverterTest, ArrayBuffer) {
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::HandleScope handle_scope(isolate_);
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Local<v8::Context> context =
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      v8::Local<v8::Context>::New(isolate_, context_);
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Context::Scope context_scope(context);
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<GinJavaBridgeValueConverter> converter(
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new GinJavaBridgeValueConverter());
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Handle<v8::ArrayBuffer> v8_array_buffer(
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      v8::ArrayBuffer::New(isolate_, 0));
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<base::Value> undefined(
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      converter->FromV8Value(v8_array_buffer, context));
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(undefined.get());
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(GinJavaBridgeValue::ContainsGinJavaBridgeValue(undefined.get()));
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<const GinJavaBridgeValue> undefined_value(
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GinJavaBridgeValue::FromValue(undefined.get()));
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(undefined_value.get());
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(undefined_value->IsType(GinJavaBridgeValue::TYPE_UNDEFINED));
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(GinJavaBridgeValueConverterTest, TypedArrays) {
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::HandleScope handle_scope(isolate_);
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Local<v8::Context> context =
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      v8::Local<v8::Context>::New(isolate_, context_);
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  v8::Context::Scope context_scope(context);
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<GinJavaBridgeValueConverter> converter(
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new GinJavaBridgeValueConverter());
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const char* source_template = "(function() {"
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "var array_buffer = new ArrayBuffer(%s);"
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "var array_view = new %s(array_buffer);"
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "array_view[0] = 42;"
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "return array_view;"
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "})();";
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const char* array_types[] = {
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "1", "Int8Array", "1", "Uint8Array", "1", "Uint8ClampedArray",
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "2", "Int16Array", "2", "Uint16Array",
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "4", "Int32Array", "4", "Uint32Array",
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "4", "Float32Array", "8", "Float64Array"
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < arraysize(array_types); i += 2) {
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const char* typed_array_type = array_types[i + 1];
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    v8::Handle<v8::Script> script(v8::Script::Compile(v8::String::NewFromUtf8(
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        isolate_,
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::StringPrintf(
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            source_template, array_types[i], typed_array_type).c_str())));
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    v8::Handle<v8::Value> v8_typed_array = script->Run();
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<base::Value> list_value(
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        converter->FromV8Value(v8_typed_array, context));
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(list_value.get()) << typed_array_type;
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(list_value->IsType(base::Value::TYPE_LIST)) << typed_array_type;
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::ListValue* list;
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(list_value->GetAsList(&list)) << typed_array_type;
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(1u, list->GetSize()) << typed_array_type;
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    double first_element;
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(list->GetDouble(0, &first_element)) << typed_array_type;
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(42.0, first_element) << typed_array_type;
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace content
139